将 OrderBy 表达式与 Where 表达式组合在一起

本文关键字:表达式 组合 在一起 Where OrderBy | 更新日期: 2023-09-27 18:37:18

我发现了以下可以组合多个Expression<Func<T,bool>>表达式的问题:

如何在不调用的情况下合并两个 C# Lambda 表达式?

我想知道是否使用类似的技术,您如何合并.排序者 Expression<Func<Entity, Key>> 带有 .如果Expression<Func<Entity, bool>>到一个类型的表达式中,或从类型继承,则System.Linq.Expressions.Expression .

我正在制作一个真正削减的 QueryProvider 风格的类,用于通过公共方法.Where.OrderBy获取T => T == ... Func。这样做的目的是将此类构建的表达式传递给 QueryTranslator 以创建合适的 SQL。

这种样式的 QueryTranslator 在从 QueryProvider 调用时,通常将一个System.Linq.Expressions.Expression作为参数,然后将其转换为 SQL。

我可以跟进并理解上述合并两个.Where Func的问题。以下博客文章对此特别有用,我追溯了每个示例:

http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx

这篇代码项目文章也很有用:

http://www.codeproject.com/Articles/24255/Exploring-Lambda-Expression-in-C

当组合 .OrderBy Func with a .然而,Func 两者有不同的通用参数。在 .如果它是一个Func<Entity, bool>,而在 .订购 这是一个Func<Entity, Key> .

从表面上看,合并这两个表达式并不像合并两个具有相同泛型参数的表达式那样简单。

内置的 Func-Expression-progening-engine(不确定确切术语)能够组合一个 .其中 Func 带有 .按函数订购。我很好奇当这两个表达式合并为一个System.Linq.Expressions.Expression时,引擎盖下会发生什么。 是否有可能,如果是,假设每个表达式中的实体属于相同类型,您将如何将Expression<Func<Entity, bool>>Expression<Func<Entity,Key>>组合在一起?

将 OrderBy 表达式与 Where 表达式组合在一起

public IQueryable<T> ApplyExpressions<T, TKey>(
  Expression<Func<T, TKey>> sortBy,
  Expression<Func<T, bool>> filterBy,
  IQueryable<T> source)
{
  return source.Where(filterBy).OrderBy(sortBy);
}

IQueryable<Customer> query = ApplyExpressions<Customer, int>(
  c => c.Age,
  c => c.Name.StartsWith("B"),
  myDC.Customers)
Expression queryExpression = query.Expression;  //tada

我认为这个问题模棱两可的地方是因为它有点无法回答。

我试图构建一个超级表达式,就像IQueryable<>表达式生成器如何在一个表达式中处理.Where.OrderBy表达式一样。

然而,如果没有主题,我对表达式和表达式树的有限理解似乎表明这是不可能的。

要将.Where表达式与.OrderBy表达式组合成一个表达式,您需要MethodCallExpression 来分隔两个LambdaExpression

MethodCallExpression需要一个主题来调用该方法。这就是使用IQueryable<>的地方。

我已经更改了我的 Query 类以保持所有LambdaExpression的独立,然后将它们分别传递给 QueryTranslator。QT 将输出 SQL 合并到正确的位置。

这与分析一个超级表达式并根据表达式中的MethodCallExpression将SQL输出到正确位置的IQueryable<> QueryProvider相反。