我正在使用谓词生成器编写以下代码:
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 48 在 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
仅当您执行查询时才会评估,此时value of id
是最后一项ids
收藏。的行为foreach
这方面将在 C# 5 中进行更改,这将不再是问题。欲了解更多信息,请阅读“关闭循环变量被认为是有害的” http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)