我如何动态构造一个用于匿名类型的表达式树

问题描述 投票:5回答:1

这是我在这里的第一篇文章。如果我违反了任何准则,请告诉我,我们将很乐意更正它们。

我有以下实体类:

public class Book
{
public int BookID { get; set; }
public string Author { get; set; }
public string Publisher { get; set; }
}

以及第二个实体类,

public class Library
{
public int ID  { get; set; } 
public Book Book { get; set; }
public int Count { get; set; }
}

我也具有此功能,可以根据用户输入动态生成lambda表达式。

public static Expression<Func<T, bool>> GetLambdaExpression<T>(List<Operation> OperationList)
        {  
            ExpressionTree expressionTree = new ExpressionTree();
            Node Root = expressionTree.ConstructTree(OperationList);

            var Parameter = Expression.Parameter(typeof(T), "x");
            var Expression = CalculateExpression(Root);  //Returns an Expression Clause by And/Or every input in OperationList
            return Expression.Lambda<Func<T, bool>>(Expression, Parameter); //Finally creating Lambda
        }


Operation类包含有关操作类型,字段和值的详细信息。它从我正在通过映射字段​​名称对实体类使用查询的客户端传递过来。

代码以这种方式使用时可以正常工作,

var OperationList = //Get from client
var LambdaExpression = GetLambdaExpression<Book>(OperationList);
var result = _BookContext.Books.Where(LambdaExpression);

OR

var OperationList = //Get from client
var LambdaExpression = GetLambdaExpression<Library>(OperationList);
var result = _LibraryContext.Library.Where(LambdaExpression);

我正在尝试使用LINQ连接两个Entity类,但是我似乎找不到一种为JOIN返回的生成的匿名类型动态创建Lambda表达式的方法。

我的加入看起来像,

 var result = from c in _BookContext.Books

              join d in _LibraryContext.Library

              on c.BookID equals d.ID

              select new { c , d };

但是,由于明显的原因,这将不起作用,

var OperationList = //Passed from client
var LambdaExpression = GetLambdaExpression<T>(OperationList);
result.Where(LambdaExpression); 

将'object'或'dynamic'传递给GetLambdaExpression()无效,因为字段名不是预定义的,并且会引发异常。

我如何为匿名类型构造一个表达式树。

非常感谢。

c# entity-framework linq lambda expression-trees
1个回答
0
投票

如何制定扩展方法?像这样:

public static class QueryExpression
{
    public static IQueryable<T> WhereWithLambdaExpression<T>(
        this IQueryable<T> query, List<Operation> OperationList)
    {
        ExpressionTree expressionTree = new ExpressionTree();
        Node Root = expressionTree.ConstructTree(OperationList);

        var Parameter = Expression.Parameter(typeof(T), "x");
        //Returns an Expression Clause by And/Or every input in OperationList
        var Expression = CalculateExpression(Root);

        //Finally creating Lambda
        Expression<Func<T, bool>> predicate =
            Expression.Lambda<Func<T, bool>>(Expression, Parameter); 

        return query.Where(predicate);
    }
}

然后

var query = joinResults.WhereWithLambdaExpression(OperationList);
© www.soinside.com 2019 - 2024. All rights reserved.