嵌套或使用Linq PredicateBuilder

嵌套或使用Linq PredicateBuilder,linq,predicatebuilder,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

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

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();
IEnumerable id=新列表{47,48};
var predicate=PredicateBuilder.False();
predicate=predicate.And(x=>x.CreatedAt>=fromDate&&x.CreatedAt x.Source.Id==Id);
}
var result=Database.Set().AsExpandable()
.Where(谓词)
.ToList();
生成的SQL如下所示(仅WHERE子句):

其中(@p\u linq\u 0,@p\u linq\u 1)中的([Filter6].[SourceId]
和([Filter6].[CreatedAt]>=@p\u linq\u 2)
和([Filter6].[CreatedAt]
您正在关闭循环变量。请制作
id
变量的本地副本:

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

由于Linq是惰性的,
谓词,因此只有在执行查询时才会计算
id
,此时
id
的值是
id
集合中的最后一项。在这方面,
foreach
的行为将在C#5中更改,这不再是问题。For更多信息阅读

如果这就是您正在做的事情,并且您的列表不长,那么您根本不需要谓词生成器

 var result = Database.Set<Customer>().AsExpandable() 
                                      .Where( x => x.CreatedAt >= fromDate
                                                   && x.CreatedAt <= toDate
                                                   && ids.Contains( x.Source.Id ) ) 
                                      .ToList();
var result=Database.Set().AsExpandable()
。其中(x=>x.CreatedAt>=fromDate
&&x.CreatedAt x.CreatedAt>=fromDate&&x.CreatedAt x.Source.Id==localId);
}
谓词=谓词和(idPredicate);
foreach (var id in ids)
{
    int localId = id;
    predicate = predicate.Or(x => x.Source.Id == localId);
}
 var result = Database.Set<Customer>().AsExpandable() 
                                      .Where( x => x.CreatedAt >= fromDate
                                                   && x.CreatedAt <= toDate
                                                   && ids.Contains( x.Source.Id ) ) 
                                      .ToList();
// This should translate to True AND (u AND x) AND (FALSE OR y OR z)
var predicate = PredicateBuilder.True<Customer>();

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

var idPredicate = PredicateBuilder.False<Customer>();      
foreach (var id in ids)      
{   
    var localId = id;   
    idPredicate = idPredicate.Or(x => x.Source.Id == localId);      
}

predicate = predicate.And( idPredicate );