gpt4 book ai didi

c# - 如何动态构建表达式树以用于匿名类型

转载 作者:行者123 更新时间:2023-12-03 17:12:11 25 4
gpt4 key购买 nike

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

我有以下实体类:

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
}



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

以这种方式使用时,代码按预期工作,
var OperationList = //Get from client
var LambdaExpression = GetLambdaExpression<Book>(OperationList);
var result = _BookContext.Books.Where(LambdaExpression);

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


我正在尝试使用 LINQ 加入两个实体类,但我似乎无法找到一种方法来为由 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);


将“对象”或“动态”传递给 GetLambdaExpression() 不起作用,因为字段名称不是预定义的,并且会引发异常。

如何为匿名类型构建表达式树。

非常感谢。

更新

我设法解决了它。这是我所做的:

我没有将联接的结果存储到匿名类型中,而是创建了一个新类,该类具有用于执行联接的实体类的对象。
public class JoinResult
{
public Book Book { get; set; }
public Library Library { get; set; }
}

执行连接并将数据存储到 JoinResult
var result = from c in _BookContext.Books

join d in _LibraryContext.Library

on c.BookID equals d.ID

select new JoinResult{ Book = c , Library = d };

最后,这是为 JoinResult 动态创建 Lambda 表达式的技巧。

我为 JoinResult 创建了一个表达式参数,然后为 JoinResult 的属性创建了表达式属性。

我使用创建的表达式属性作为参数传递给实体类的新属性。本质上,以“x.Book.BookID”格式创建属性。

例如,如果我想对 JoinResult 执行 EqualOperation。这是我将如何做到的。
public static IQueryable<T> PerformEqualOperation<T>(int Constant, int FieldName, Type Prop, IQueryable<T> resultOfJoin)
{

var Parameter = Expression.Parameter(typeof(T), "x"); //x
PropertyInfo[] Properties = typeof(T).GetProperties(); //Get the properties of JoinResult

string propertyname;

//Get the property name
foreach(var property in Properties)
{
if(property.GetType() == Prop)
propertyname = property.Name;
}

//Creating a property that can be passed as a parameter to the property for Entity class.
var expressionparameter = Expression.Property(Parameter, propertyname); //x.Book
var expressionproperty = Expression.Property(expressionparameter, FieldName);//x.Book.BookID
var expressionclause = Expression.Equal(expressionproperty, Expression.Constant(Constant));//x.Book.BookID == Constant
var expressionlambda = Expression.Lambda<Func<T,bool>>(expressionclause, Parameter)
return resultOfJoin.Where(expressionlambda).AsQueryable();
}

希望这可以帮助

最佳答案

制作扩展方法怎么样?像这样:

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);

编译器可以从 IQueryable<T> 推断匿名类型并将其传递为 T到扩展方法。

关于c# - 如何动态构建表达式树以用于匿名类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60926948/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com