Tho*_*mas 2 linq predicatebuilder
我使用谓词构建器编写以下代码:
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子句):
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在SQL中被分配了两次.不知道为什么?
foreach (var id in ids)
{
    predicate = predicate.Or(x => x.Source.Id == id);
}
您正在关闭循环变量.id改为制作变量的本地副本:
foreach (var id in ids)
{
    int localId = id;
    predicate = predicate.Or(x => x.Source.Id == localId);
}
由于LINQ的是懒惰的Or谓词,因此id仅会在您执行查询和评估当时的价值的id是在最后一个项目ids集合.foreach在这方面的行为将在C#5中改变,这将不再是一个问题.有关更多信息,请阅读"关闭循环变量被视为有害"