Bri*_*Tax 2 .net linq many-to-many entity-framework expression-trees
我正在尝试构建一个实体框架4多对多关系过滤器,这是一个动态数据项目.我知道我需要在运行时构建一个表达式树,而且我很熟悉这样做类似于这样的表达式:
private MethodCallExpression BuiltMethodCall(IQueryable _query, Type _ObjType, string _ColumnToSearch, string _SearchValue)
{
ConstantExpression value = Expression.Constant(_SearchValue);
ParameterExpression _parameter = Expression.Parameter(_ObjType, "value");
MemberExpression _property = Expression.Property(_parameter, _ColumnToSearch);
BinaryExpression comparison = Expression.Equal(_property, value);
LambdaExpression lambda = Expression.Lambda(comparison, _parameter);
//Ex: Customers.Select(c => c).Where(value => (value.City == "Seattle"))
MethodCallExpression _where = Expression.Call(typeof(Queryable), "Where", new Type[] { _query.ElementType }, new Expression[] {
_query.Expression,
Expression.Quote(lambda)
});
return _where;
}
Run Code Online (Sandbox Code Playgroud)
为简单起见,这些示例使用Northwind数据库,其中有多个(Customers < - CustomerCustomerDemo - > CustomerDemographics)的连接.我遇到的问题是在下面的表达式中有嵌套的lambda时构建表达式树,我在这里检索具有特定客户人口统计的所有客户.
string custDemogID = "3";
//Get customers who have a particular demog
dynamic cust = context.Customers.Where(c => c.CustomerDemographics.Any(cd => cd.CustomerTypeID == custDemogID));
Run Code Online (Sandbox Code Playgroud)
如何构建具有"where"调用的Expression树,其中包含"Any"的嵌套lambda?任何帮助都表示赞赏,即使它是如何做的伪代码.关于这个没有多少,我很绝望,请帮忙!
这是我提出的解决方案,我最大的帮助来自于从表达式调用方法 最重要的事情是创建一个通用的"Any"方法.其余的只是将呼叫链接在一起.
private MethodCallExpression BuiltMethodCall(IQueryable _query, string CustTypeID, Type _ParentObjType, Type _ChildObjType, string strChildObj, string strChildCol)
{
//This function will build a dynamic linq expression tree representing the ling calls of:
//Customers.Where(c => c.CustomerDemographics.Any(cd => cd.CustomerTypeID = custTypeID))
ConstantExpression value = Expression.Constant(CustTypeID);
//Build the outer part of the Where clause
ParameterExpression parameterOuter = Expression.Parameter(_ParentObjType, "c");
MemberExpression propertyOuter = Expression.Property(parameterOuter, strChildObj);
//Build the comparison inside of the Any clause
ParameterExpression parameterInner = Expression.Parameter(_ChildObjType, "cd");
MemberExpression propertyInner = Expression.Property(parameterInner, strChildCol);
BinaryExpression comparison = Expression.Equal(propertyInner, value);
LambdaExpression lambdaInner = Expression.Lambda(comparison, parameterInner);
//Create Generic Any Method
Func<MethodInfo, bool> methodLambda = m => m.Name == "Any" && m.GetParameters().Length == 2;
MethodInfo method = typeof(Enumerable).GetMethods().Where(methodLambda).Single().MakeGenericMethod(_ChildObjType);
//Create the Any Expression Tree and convert it to a Lambda
MethodCallExpression callAny = Expression.Call(method, propertyOuter, lambdaInner);
LambdaExpression lambdaAny = Expression.Lambda(callAny, parameterOuter);
//Build the final Where Call
MethodCallExpression whereCall = Expression.Call(typeof(Queryable), "Where", new Type[] { _query.ElementType }, new Expression[] {
_query.Expression,
Expression.Quote(lambdaAny)
});
return whereCall;
Run Code Online (Sandbox Code Playgroud)
}
| 归档时间: |
|
| 查看次数: |
1996 次 |
| 最近记录: |