当前位置:  开发笔记 > 编程语言 > 正文

组合多个表达式(Expression <Func <T,bool >>)不使用变量.为什么?

如何解决《组合多个表达式(Expression<Func<T,bool>>)不使用变量.为什么?》经验,为你挑选了2个好方法。

好的家伙,和我一起裸露.我先总结一下,然后再详细说明.

我编写了许多方法(.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 IQueryable WhereOr(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



1> Brian..:

我甚至不再费心阅读问题机构,我只是读了标题,然后说

看到

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


不,这是通常的事情,虽然有一个扭曲(他没有关闭一个循环变量,他正在分配一个变量_explicitly_声明_outside_循环,然后关闭它).

2> Pavel Minaev..:

"如何修复"答案.改变这个:

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给出了"什么和为什么"的答案.

推荐阅读
手机用户2402852307
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有