需要帮助转换“Any()” lambda到表达式树 [英] Need help converting "Any()" lambda to an expression tree
问题描述
请考虑以下几点。 (这是有效的,但是我需要帐号作为一个字符串传递。帐户是帐户列表)
Consider the following. (which works, but I need Accounts to be passed in as a string. Accounts is list of Account)
repo = repo.Where(x => x.Accounts.Any(p => p.Id == 1));
这是我到目前为止,但我似乎无法将它们连线在一起。
Here is what I have so far, but I can't seem to wire them together at the end.
var parameterExp = Expression.Parameter(typeof(Car), "x");
Expression propertyExp = Expression.Property(parameterExp, "Accounts");
//Type elementType = propertyExp.Type.GetGenericArguments()[0];
MethodInfo AnyMethod = typeof(Enumerable).GetMethods(BindingFlags.Public | BindingFlags.Static).First(m => m.Name == "Any");
var parameterExp2 = Expression.Parameter(typeof(Car), "p");
var idExpr = Expression.PropertyOrField(parameterExp2, "Id");
MethodInfo method = typeof(long).GetMethod("Equals", new[] { typeof(long) });
var _relatedToId = Expression.Constant(relatedToId, typeof(long));
var equalsMethodExp = Expression.Call(idExpr, method, _relatedToId);
// This is where it breaks. I can't seem to wire it together correctly.
var call = Expression.Call(
AnyMethod,
propertyExp,
equalsMethodExp);
Expression<Func<Car, bool>> predicate = Expression.Lambda<Func<Car, bool>>(call, parameterExp);
// Need to return x => x.Accounts.Any(p => p.Id.Equals(1))
return predicate;
提前感谢
推荐答案
您有几个错误:
-
首先,取消注释下面的
Firstly, uncomment line below
Type elementType = propertyExp.Type.GetGenericArguments()[0];
其次,您不正确地检索 MethodInfo
为任何
。您需要包含两个参数(source,func)的信息,您需要获取任何任何< Account>
的封闭类型,而不是打开 Any< < / code>:
Secondly, you don't correctly retrieve MethodInfo
for Any
. You need info that contains two parameters (source, func) and you need to get the closed type of Any Any<Account>
not the open Any<>
:
MethodInfo AnyMethod = typeof(Enumerable)
.GetMethods(BindingFlags.Public | BindingFlags.Static)
.First(m => m.Name == "Any" && m.GetParameters().Length > 1);
var closedAnyMethod = AnyMethod.MakeGenericMethod(elementType);
第三, parameterExp2
。它应该是帐户
不汽车
:
var parameterExp2 = Expression.Parameter(elementType, "p");
第四,你应该转换一个 MethodCallExpression
for 等于方法到lambda表达式。您不能直接将等于'调用表达式传递给任何
,因为任何
获取 Func< T,bool>
作为参数:
Fourthly, you should convert a MethodCallExpression
for Equals method to lambda expression. You cannot directly pass Equals' call expression to Any
because Any
gets Func<T, bool>
as parameter:
var equalsMethodExp = Expression.Call(idExpr, method, _relatedToId);
var lambdaAny = Expression.Lambda(typeof(Func<,>).MakeGenericType(elementType, typeof(bool)), equalsMethodExp, parameterExp2);
最后,您只需要调用另一个覆盖 Expression即可。调用
:
var call = Expression.Call(
closedAnyMethod,
propertyExp,
lambdaAny);
让我知道如果你想得到完整的代码。
Let me know if you want to get the complete code.
这篇关于需要帮助转换“Any()” lambda到表达式树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!