嵌套或使用Linq PredicateBuilder [英] Nesting OR using Linq PredicateBuilder

查看:91
本文介绍了嵌套或使用Linq PredicateBuilder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用谓词生成器来编写以下代码:

I am using predicate builder to write the following code:

IEnumerable<int> ids= new List<int> { 47, 48 };

var predicate = PredicateBuilder.False<Customer>();

predicate = predicate.And(x => x.CreatedAt >= fromDate && x.CreatedAt <= toDate);

foreach (var id in ids)
{
    predicate = predicate.Or(x => x.Source.Id == id);
}

var result = Database.Set<Customer>().AsExpandable()
                                     .Where(predicate)
                                     .ToList();

生成的SQL看起来像(只是WHERE子句):

The SQL generated looks like (just the WHERE clause):

WHERE ([Filter6].[SourceId] IN (@p__linq__0,@p__linq__1))
AND ([Filter6].[CreatedAt] >= @p__linq__2)
AND ([Filter6].[CreatedAt] <= @p__linq__3)',
N'@p__linq__0 int,
@p__linq__1 int,
@p__linq__2 datetime2(7),
@p__linq__3 datetime2(7)',
@p__linq__0=48,
@p__linq__1=48,
@p__linq__2='2012-02-07 21:59:55.0437985',
@p__linq__3='2012-02-07 22:04:55.5748288'

似乎ID 48在SQL中分配了两次.不知道为什么吗?

It looks like id 48 got assigned twice in the SQL. Not sure why?

推荐答案

foreach (var id in ids)
{
    predicate = predicate.Or(x => x.Source.Id == id);
}

您正在关闭循环变量.改为创建您的id变量的本地副本:

You are closing over the loop variable. Make a local copy of your id variable instead:

foreach (var id in ids)
{
    int localId = id;
    predicate = predicate.Or(x => x.Source.Id == localId);
}

由于Linq懒惰了您的Or谓词,因此id仅在执行查询时被评估,并且那时id value ids集合.在这方面foreach的行为将在C#5中更改,在此不再是问题.有关更多信息,请阅读

Since Linq is lazy your Or predicate and hence id will only be evaluated when you execute the query and at that time the value of id is the last item in the ids collection. The behavior of foreach in this regard will be changed in C# 5 where this will not be a problem anymore. For more info read "Closing over the loop variable considered harmful"

这篇关于嵌套或使用Linq PredicateBuilder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆