【问题标题】:Does the order of calls to IEnumerable<T>-functions affect the final query when using Entity Framework?使用实体框架时,对 IEnumerable<T> 函数的调用顺序是否会影响最终查询?
【发布时间】:2010-02-17 09:10:32
【问题描述】:

在Entity框架中,会不会声明

MyDataContext.Products.OrderByDescending( (p) => p.Id ).GroupBy<Product,int>( (p) => p.ProductId ).Select( (g) => g.FirstOrDefault()).Where( (p) => p.Name.Equals("Something") );

导致另一个数据库查询而不是

MyDataContext.Products.Where( (p) => p.Name.Equals("Something") ).OrderByDescending( (p) => p.Id ).GroupBy<Product,int>( (p) => p.ProductId ).Select( (g) => g.FirstOrDefault());

换句话说,对 Where() 和 GroupBy() 的调用顺序是否会影响对数据库的最终查询?还是实体框架足够聪明来解决这个问题?

我想知道的原因是,在我正在开发的系统中,我们需要跟踪对产品行的所有更改。我们使用的解决方案是在表中插入一个新的产品行,而不是更新它。然后使用“ProductId”字段将产品的不同版本组合在一起。因此,我想将“分组”逻辑移至外部方法,但仍允许调用者指定 Where 条件……所以我的目标是使用第一种方法。

【问题讨论】:

  • 为什么不使用分析器工具(例如SQL Server profiler)来看看执行的查询有什么不同?
  • 感谢您的提示,这实际上是我的第一个想法,但我在 SQL Server 上没有足够的权限......但我总是可以在 SQL Server 上安装数据库的本地副本以这种方式表达并尝试..

标签: c# entity-framework generics ienumerable


【解决方案1】:

是的,这很重要。 The EF may silently ignore OrderBy calls which come before Where calls。这应该不足为奇,因为 SQL 查询不支持 ORDER BY 之前的 WHERE,在子查询之外。

请注意,即使考虑到这一点,您仍然可以“将‘分组’逻辑移至外部方法,但仍允许调用者指定 Where 条件”:

var q = SomeQuery
        .Where(GeneratePredicate())
        .GroupBy(GenerateSelector<string>());

你有这样的方法:

public Expresssion<Func<SomeEntity, bool>> GeneratePredicate
{
     return e => e.Id == 123;
}

public Expression<Func<SomeEntity, T>> GenerateSelector<T>()
{
     return e => e.GroupField;
}

重要的是,这些WhereGroupBy 调用不是 IEnumerable&lt;T&gt; 的方法;它们是IQueryable&lt;T&gt; 的方法,这就是它们完全可以转换为SQL 的原因。

【讨论】:

  • 感谢您的好回答!嗯......对 OrderByDescending() 的调用已完成,因为我想检索产品的正确(或最后)版本。然后我只需选择组中的第一个项目即可。您的意思是如果我在之后调用 Where 可以忽略此顺序吗?没想到这么多,谢谢你的提示!
  • 是的,确实如此。您可能想使用First(Expression) 而不是OrderBy().First()
猜你喜欢
  • 1970-01-01
  • 2014-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多