Entity framework 为实体框架多对多关系构建表达式树?

Entity framework 为实体框架多对多关系构建表达式树?,entity-framework,linq,linq-to-sql,many-to-many,expression-trees,Entity Framework,Linq,Linq To Sql,Many To Many,Expression Trees,我正在为以下结构编写代码: 3张桌子 表“图书”、“图书作者”和“作者” 现在,我想构建一个ExpressionTree以获得以下Linq结果: _ent.Book.Where(c => c.BookAuthor.Any(cd => cd.Author.AuthorName == "test")); 我的问题是到达cd.Author.AuthorName(或类似内容)的最后一个表达式。 我当前的代码: private MethodCallExpression BuiltMetho

我正在为以下结构编写代码:
3张桌子

表“图书”、“图书作者”和“作者”

现在,我想构建一个ExpressionTree以获得以下Linq结果:

_ent.Book.Where(c => c.BookAuthor.Any(cd => cd.Author.AuthorName == "test"));
我的问题是到达
cd.Author.AuthorName
(或类似内容)的最后一个表达式。

我当前的代码:

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:
        //Book.Where(c => c.BookAuthor.Any(cd => cd.Author = 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;
    }
private MethodCallExpression BuiltMethodCall(IQueryable\u查询,字符串CustTypeID,类型\u ParentObjType,
类型_ChildObjType,字符串strChildObj,字符串strChildCol)
{
//此函数将构建一个动态linq表达式树,表示以下的ling调用:
//Book.Where(c=>c.BookAuthor.Any(cd=>cd.Author=custypeid))
ConstantPression值=表达式常数(CustTypeID);
//构建Where子句的外部部分
ParameterExpression parameterOuter=表达式参数(_ParentObjType,“c”);
MemberExpression PropertyYouter=Expression.Property(参数外部,strChildObj);
//在Any子句内部构建比较
ParameterExpression parameterInner=表达式参数(_ChildObjType,“cd”);
MemberExpression propertyInner=Expression.Property(参数inner,strChildCol);
BinaryExpression比较=Expression.Equal(propertyInner,value);
LambdaExpression lambdaInner=Expression.Lambda(比较,参数化);
//创建泛型任意方法
Func methodLambda=m=>m.Name==“任意”&&m.GetParameters().Length==2;
MethodInfo method=typeof(可枚举).GetMethods().Where(methodLambda).Single()
.MakeGenericMethod(_ChildObjType);
//创建任意表达式树并将其转换为Lambda
MethodCallExpression callAny=Expression.Call(方法,PropertyYouter,lambdainer);
LambdaExpression lambdany=Expression.Lambda(callAny,parameterOuter);
//构建最终Where调用
MethodCallExpression whereCall=Expression.Call(typeof(Queryable),“Where”,
新类型[]{u query.ElementType},新表达式[]
{
_query.Expression,
Expression.Quote(lambdany)
});
回电;
}

如果我理解正确,您正在询问如何创建嵌套属性访问器表达式

在技术和方法的帮助下,这很容易

下面是一个自定义扩展方法,可以用作
表达式。属性
方法替换:

public static partial class ExpressionExtensions
{
    public static MemberExpression Property(this Expression instance, string path)
    {
        return (MemberExpression)path.Split('.').Aggregate(instance, Expression.Property);
    }
}
它使用
分隔符(例如
“BookAuthor”
“Author.AuthorName”
)正确处理
字符串中编码的简单属性和嵌套属性

所以不是

MemberExpression propertyOuter = Expression.Property(parameterOuter, strChildObj);

您可以安全地使用

MemberExpression propertyOuter = parameterOuter.Property(strChildObj);

MemberExpression propertyOuter = parameterOuter.Property(strChildObj);
MemberExpression propertyInner = parameterInner.Property(strChildCol);