我编写了许多方法(.WhereOr,.WhereAnd),这些方法基本上允许我“堆叠”一堆lambda查询,然后将它们应用到集合中。例如,数据集的用法有点像这样(虽然它可以通过使用泛型与任何类一起使用):
WITH LINQ TO DATASETS(使用.NET DataSetExtensions)
DataTable Result;
List<Expression<Func<DataRow, bool>> Queries = new List<Expression<Func<DataRow, bool>>();
Queries.Add(dr=> dr.Field<string>("field1") == "somestring");
Queries.Add(dr=> dr.Field<string>("field2") == "somestring");
Queries.Add(dr=> dr.Field<string>("field3") == "somestring");
Result = GetSomeTable().AsEnumarable().WhereOr(Queries).CopyToDataTable();
现在说在上面的例子中,集合中只有一行匹配“somestring”,而它位于字段“field2”上。
这意味着Result的计数应为1。
现在,我说稍微重写以上代码:
DataTable Result;
List<Expression<Func<DataRow, bool>> Queries = new List<Expression<Func<DataRow, bool>>();
List<string> columns = new string[]{"field1","field2","field3"}.ToList();
string col;
foreach(string c in columns){
col = c;
Queries.Add(dr=> dr.Field<string>(col) == "somestring");
}
Result = GetSomeTable().AsEnumarable().WhereOr(Queries).CopyToDataTable();
现在,我并不真正理解表达,但对我来说,上面的两个例子都做了完全相同的事情。
第一个示例中的“Result”的计数为1,第二个示例中的“Result”的计数为0。
此外,在第二个示例的List列中,如果将“field2”设置为last,而不是second,则“Result”的计数正确为1。
所以,从这一切来看,我得出了一个结论,但我真的不明白发生了什么,也不知道如何解决它......?我可以更早地“评估”那些表达式......还是其中的一部分?
结论:
基本上,似乎,如果我将文字值发送到那里,比如“field1”,它就可以了。但是如果我发送变量,比如“col”,它就不起作用,因为这些“表达式”只会在代码中稍后进行评估。
这也可以解释为什么当我将“field2”移动到最后位置时它的工作原理。它的工作原理是因为变量“col”最后被分配给“field2”,因此当表达式评估“col”等于“field2”时。
好的,那么,有什么方法吗?
这是我的WhereOr方法的代码(它是IENumerable的扩展方法):
public static IQueryable<T> WhereOr<T>(this IEnumerable<T> Source, List<Expression<Func<T, bool>>> Predicates) {
Expression<Func<T, bool>> FinalQuery;
FinalQuery = e => false;
foreach (Expression<Func<T, bool>> Predicate in Predicates) {
FinalQuery = FinalQuery.Or(Predicate);
}
return Source.AsQueryable<T>().Where(FinalQuery);
}
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> Source, Expression<Func<T, bool>> Predicate) {
InvocationExpression invokedExpression = Expression.Invoke(Predicate, Source.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.Or(Source.Body, invokedExpression), Source.Parameters);
}
答案 0 :(得分:6)
我甚至不再费心阅读问题机构了,我只是读了标题,然后说
见
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!689.entry
和
答案 1 :(得分:6)
“如何修复”答案。改变这个:
string col;
foreach(string c in columns) {
col = c;
Queries.Add(dr=> dr.Field<string>(col) == "somestring");
}
到此:
foreach(string c in columns) {
string col = c;
Queries.Add(dr=> dr.Field<string>(col) == "somestring");
}
享受。布莱恩给出了“什么和为什么”的答案。
答案 2 :(得分:1)
答案 3 :(得分:0)
我找到了很好的文章来满足你的要求
该链接提供And<T>
和Or<T>
扩展方法来制作它。
http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx