好的家伙,和我一起裸露.我先总结一下,然后再详细说明.
我编写了许多方法(.WhereOr,.WhereAnd),基本上允许我"堆叠"一堆lambda查询,然后将它们应用到集合中.例如,数据集的用法有点像这样(虽然它可以通过使用泛型与任何类一起使用):
使用LINQ TO DATASETS(使用.NET DataSetExtensions)
DataTable Result; List> Queries = new List >(); Queries.Add(dr=> dr.Field ("field1") == "somestring"); Queries.Add(dr=> dr.Field ("field2") == "somestring"); Queries.Add(dr=> dr.Field ("field3") == "somestring"); Result = GetSomeTable().AsEnumarable().WhereOr(Queries).CopyToDataTable();
现在说在上面的例子中,集合中只有一行匹配"somestring",而它位于字段"field2"上.
这意味着Result的计数应为1.
现在,假设我稍微重写上面的代码:
DataTable Result; List> Queries = new List >(); List columns = new string[]{"field1","field2","field3"}.ToList(); string col; foreach(string c in columns){ col = c; Queries.Add(dr=> dr.Field (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 IQueryableWhereOr (this IEnumerable Source, List >> Predicates) { Expression > FinalQuery; FinalQuery = e => false; foreach (Expression > Predicate in Predicates) { FinalQuery = FinalQuery.Or(Predicate); } return Source.AsQueryable ().Where(FinalQuery); } public static Expression > Or (this Expression > Source, Expression > Predicate) { InvocationExpression invokedExpression = Expression.Invoke(Predicate, Source.Parameters.Cast ()); return Expression.Lambda >(Expression.Or(Source.Body, invokedExpression), Source.Parameters); }
Brian.. 6
我甚至不再费心阅读问题机构,我只是读了标题,然后说
看到
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!689.entry
和
http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx
我甚至不再费心阅读问题机构,我只是读了标题,然后说
看到
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!689.entry
和
http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx
"如何修复"答案.改变这个:
string col; foreach(string c in columns) { col = c; Queries.Add(dr=> dr.Field(col) == "somestring"); }
对此:
foreach(string c in columns) { string col = c; Queries.Add(dr=> dr.Field(col) == "somestring"); }
请享用.Brian给出了"什么和为什么"的答案.