附加到一个表达式 [英] Append to an expression
问题描述
我跟着这个线程:链接文本
杰森举了一个例子:
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.Func
2[Models.Order,System.Boolean]' and 'System.Func
2[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 $ C ?$ C>表达式
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屋!