gpt4 book ai didi

c# - 表达式列表 >

转载 作者:可可西里 更新时间:2023-11-01 08:42:01 25 4
gpt4 key购买 nike

我正在寻找一种方法来存储 Expression<Func<T, TProperty>> 的集合用于对元素进行排序,然后针对 IQueryable<T> 执行存储的列表对象(底层提供者是 Entity Framework )。

例如,我想做这样的事情(这是伪代码):

public class Program
{
public static void Main(string[] args)
{
OrderClause<User> orderBys = new OrderClause<User>();
orderBys.AddOrderBy(u => u.Firstname);
orderBys.AddOrderBy(u => u.Lastname);
orderBys.AddOrderBy(u => u.Age);

Repository<User> userRepository = new Repository<User>();
IEnumerable<User> result = userRepository.Query(orderBys.OrderByClauses);
}
}

一个 order by 子句(要订购的属性):

public class OrderClause<T>
{
public void AddOrderBy<TProperty>(Expression<Func<T, TProperty>> orderBySelector)
{
_list.Add(orderBySelector);
}

public IEnumerable<Expression<Func<T, ???>>> OrderByClauses
{
get { return _list; }
}
}

带有我的查询方法的存储库:

public class Repository<T>
{
public IEnumerable<T> Query(IEnumerable<OrderClause<T>> clauses)
{
foreach (OrderClause<T, ???> clause in clauses)
{
_query = _query.OrderBy(clause);
}

return _query.ToList();
}
}

我的第一个想法是转换 Expression<Func<T, TProperty>>成一个字符串(要排序的属性名称)。所以基本上,我没有存储类型列表(这是不可能的,因为 TProperty 不是常量),而是存储一个字符串列表,其中包含要排序的属性。

但这行不通,因为我无法重建 Expression返回(我需要它,因为 IQueryable.OrderBy 将 Expression<Func<T, TKey>> 作为参数)。

我还尝试动态创建表达式(在 Expression.Convert 的帮助下),以获得 Expression<Func<T, object>>但后来我从 Entity Framework 中得到一个异常,说它无法处理 Expression.Convert 语句。

如果可能,我不想使用像 Dynamic Linq Library 这样的外部库.

最佳答案

这是动态/反射解决方案可能适用的少数情况之一。

我想你想要这样的东西? (我已经阅读了字里行间的内容,并在我认为必要的地方对您的结构进行了一些更改)。

public class OrderClauseList<T>
{
private readonly List<LambdaExpression> _list = new List<LambdaExpression>();

public void AddOrderBy<TProperty>(Expression<Func<T, TProperty>> orderBySelector)
{
_list.Add(orderBySelector);
}

public IEnumerable<LambdaExpression> OrderByClauses
{
get { return _list; }
}
}

public class Repository<T>
{
private IQueryable<T> _source = ... // Don't know how this works

public IEnumerable<T> Query(OrderClause<T> clauseList)
{
// Needs validation, e.g. null-reference or empty clause-list.

var clauses = clauseList.OrderByClauses;

IOrderedQueryable<T> result = Queryable.OrderBy(_source,
(dynamic)clauses.First());

foreach (var clause in clauses.Skip(1))
{
result = Queryable.ThenBy(result, (dynamic)clause);
}

return result.ToList();
}
}

关键技巧是让 C# dynamic 为我们执行可怕的重载解析和类型推断。更重要的是,我相信上面的内容,尽管使用了 dynamic,实际上是类型安全的!

关于c# - 表达式列表 <Func<T, TProperty>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16678057/

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