附加到一个表达式 [英] Append to an expression

查看:122
本文介绍了附加到一个表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我跟着这个线程:链接文本

杰森举了一个例子:

public static Expression<TDelegate> AndAlso<TDelegate>(this Expression<TDelegate> left, Expression<TDelegate> right)
{
    return Expression.Lambda<TDelegate>(Expression.AndAlso(left, right), left.Parameters);
}

和其作为这样的用法:

Expression<Func<Client, bool>> clientWhere = c => true;
if (filterByClientFName)
{
    clientWhere = clientWhere.AndAlso(c => c.ClientFName == searchForClientFName);
}
if (filterByClientLName)
{
    clientWhere = clientWhere.AndAlso(c => c.ClientLName == searchForClientLName);
}



我有一个订单表,我跟着上面的例子中,改变列名,而我得到类似的错误,该岗位的创造者不得不

I have a orders table and i followed the above example, changing column names, and i get the similar error that the post creator had

二元运算符AndAlso运算未对类型'System.Func定义 2 [Models.Order,System.Boolean]'和'System.Func 2 [Models.Order,System.Boolean]'。

The binary operator AndAlso is not defined for the types 'System.Func2[Models.Order,System.Boolean]' and 'System.Func2[Models.Order,System.Boolean]'.

任何人有我错过了任何想法

Anyone have any thoughts on what I am missing?

更新:

埃里克,我随后进一步以前的帖子的用户问什么,在这里链接文字

Eric, I further followed what the user of the previous post was asking, here link text

的用户在此

Expression<Func<Client, bool>> clientWhere = c => true;
Expression<Func<Order, bool>> orderWhere = o => true;
Expression<Func<Product, bool>> productWhere = p => true;

if (filterByClient)
{
    clientWhere = c => c.ClientID == searchForClientID;
}

现在如果他在 filterByClient各种条件,说他要么有的clientid 和/或其他列名,怎么会1个内置的 clientWhere 表达式

Now if he were to have various conditions in filterByClient, say he either has clientid and/or some other column name, how would one build the clientWhere expression?

推荐答案

您正在试图建立一个代表这个表达式树:

You're attempting to build an expression tree that represents this:

c => true && c.ClientFName == searchForClientFName

您实际上是建立一个表示这个表达式树:

You are actually building an expression tree that represents this:

c => c=> true && c => c.ClientFName == searchForClientFName



这是没有意义的。

which makes no sense at all.

现在,你可能会天真地认为这将工作:

Now, you might naively think that this will work:

public static Expression<TDelegate> AndAlso<TDelegate>(this Expression<TDelegate> left, Expression<TDelegate> right) 
{ 
// NOTICE: Combining BODIES:
    return Expression.Lambda<TDelegate>(Expression.AndAlso(left.Body, right.Body), left.Parameters); 
} 

这将产生较

c => true && c.ClientFName == searchForClientFName



这看起来正确。但实际上这是脆弱的。假设你有

Which looks right. But in fact this is fragile. Suppose you had

... d => d.City == "London" ...
... c => c.ClientName == "Fred Smith" ...

和你用这个方法把它们结合起来。你会得到较

and you used this method to combine them. You'd get an object representing

c => d.City == "London" && c.ClientName == "Fred Smith"



到底是d。在那里干什么?

What the heck is d doing in there?

此外,参数由参数名<匹配的按对象的身份的,不是的 / em>的。如果你这样做。

Furthermore, parameters are matched by object identity, not by parameter name. If you do this

... c => c.City == "London" ...
... c => c.ClientName == "Fred Smith" ...

和它们合并成

c => c.City == "London" && c.ClientName == "Fred Smith"



你是在同一条船上;在C中的c.City是的不同的C 的比其他两个。

你真正需要做的是做一个什么的第三的参数对象,的代替的这两个lambda表达式为它们的参数每一次出现的尸体,然后再建立一个的新的lambda表达式树的距离所产生的替代机构。

What you actually need to do is make a third parameter object, substitute it in the bodies of both lambdas for every occurence of their parameters, and then build up a new lambda expression tree from the resulting substituted bodies.

您可以通过编写经过该表达式树体,因为它去改写它的访问者建立一个替代引擎。

You can build a substitution engine by writing a visitor that passes over the expression tree body, rewriting it as it goes.

这篇关于附加到一个表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆