【问题标题】:C# LINQ: does the linq query only return deferred enumerable?C# LINQ:linq 查询是否只返回延迟枚举?
【发布时间】:2019-09-11 13:38:51
【问题描述】:

我有一个方法

按类别获取帖子

我可以像方法 A 那样重复使用我拥有的东西

一个

public IEnumerable<Post> GetPostsByApartmentId(
    string apartmentId,
    int pageIndex,
    int pageSize,
    int max = 50)
{
    var itemsPerPage = Math.Max(pageSize, max);
    return _context.Post
        .Where(p => p.ApartmentId == apartmentId && !p.Disabled)
        .Skip((pageIndex - 1) * itemsPerPage)
        .Take(itemsPerPage);
}

public IEnumerable<Post> GetPostsByCategory(
    string categoryId,
    string apartmentId,
    int pageIndex,
    int pageSize,
    int max = 50)
{
    return GetPostsByApartmentId(apartmentId, pageIndex, pageSize, max)
        .Where(p => p.CategoryId == categoryId);
}

但是,我担心 A 的表现, 所以这里是方法B

public IEnumerable<Post> GetPostsByCategory(
    string categoryId,
    string apartmentId,
    int pageIndex,
    int pageSize,
    int max)
{
    var itemsPerPage = Math.Max(pageSize, max);
    return _context.Post
        .Where(p => p.ApartmentId == apartmentId && !p.Disabled && p.CategoryId == categoryId)
        .Skip((pageIndex - 1) * itemsPerPage)
        .Take(itemsPerPage);
}

但是,我记得我读过一些文章说:Lambda 表达式(或 LINQ,不记得了)并没有真正执行查询,它只是构造查询,并且只有在需要时或通过调用某些东西时才会执行像 ToList()。 因此,如果是这种情况,那么 A 和 B 应该是相同的。 有人可以确认一下吗?

【问题讨论】:

  • 为什么要关注性能?究竟表现什么,一个额外的方法调用?您是否尝试过测量差异?
  • 看起来你正在使用实体框架,并且返回一个 IEnumerable 实现结果。您的实际问题是“如何扩展 Where 语句”
  • 我认为如果将GetPostsByApartmentId的返回类型更改为IQueryable&lt;Post&gt;AB之间几乎没有区别/跨度>
  • 您应该首先问一个更重要的问题:方法 A 是否返回与方法 B 相同的结果?我怀疑它没有。产生正确结果的慢代码总是比产生错误结果的快代码更可取。

标签: c# .net lambda .net-core


【解决方案1】:

选项 B 会很快,因为它可以一次性获取过滤数据。

A 将根据条件检索所有数据,然后根据类别进行过滤。它有可能最终检索到意外数据。

编辑:

如果是存储过程,它的行为方式会很有趣。

如果您可以访问探查器,那么很容易检查什么是最终的 SQL 语句返回到 sqlserver 以执行。

我不太确定,实体框架的内部机制。

但是从您的代码来看,我认为要实现相同的目标,编译器/EF 必须在幕后执行两次操作。

【讨论】:

  • 我不认为 A 自己检索任何数据。它只是返回一个延迟的枚举。使用可枚举时检索数据。
  • 感谢@TheodorZoulias 我以前读过的东西,但我找不到参考资料,你能帮忙吗?
  • @Franva 我对实体框架了解不多,所以我不熟悉它的文档。我很了解 LINQ for Objects,它的行为方式就是这样。
  • @TheodorZoulias 这是关于在数据库中执行什么,以及在本地执行什么。方法 A 将从数据库中检索 itemsPerPage 项目,然后在内存中进一步过滤它们。方法 B 在数据库中进行过滤(在将其限制为 itemsPerPage 项之前)。
  • @Franva 它被称为Deferred Execution
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多