IQueryable 和 DbQuery 有什么区别

本文关键字:什么 区别 DbQuery IQueryable | 更新日期: 2023-09-27 18:35:04

跟进这个问题/答案
如何将实体框架数据上下文设为只读

解决方案是创建 DbQuery 类型的 DbContext 集合,但这是一种相当专业的类型(它隐藏在 EF 的命名空间中)。

那么,拥有 DbContext 与此之间的功能区别是什么:

public DbQuery<Customer> Customers
{
    get { return Set<Customer>().AsNoTracking(); }
}

与此相比:

public IQueryable<Customer> Customers
{
    get { return Set<Customer>().AsNoTracking(); }
}

。EF 文档在涉及 DbQuery 类时非常轻巧,但我更喜欢让 DbContext 由接口而不是类组成的想法,所以我想避免它。DbQuery 类还提供了哪些其他好处?

更新

阅读答案并查看代码后,我意识到我的问题有点愚蠢。我还没想就问得太快了!显然,无论如何,底层的具体对象都将是一个 DbQuery,因此实际的内部功能将是相同的。在我看来,使用IQueryable是更好的选择。感谢您的耐心等待!

IQueryable 和 DbQuery 有什么区别

> DBQuery 是针对 DbContext 的非通用 LINQ to Entities 查询。公开此选项将为你提供针对实体的 LINQ 功能。如果不需要此功能,请使用IQueryable接口抽象。

IOrderedQueryable

旨在由查询提供程序实现。此接口表示调用方法排序查询的结果 OrderBy、OrderByDescending、ThenBy 或 ThenByDescending。当调用 CreateQuery 并传递表示排序查询的表达式树时,生成的 IQueryable 对象必须是实现 IOrderedQueryable 的类型。

IListSource 

为对象提供返回可绑定到数据源的列表的功能。

IDbAsyncEnumerable

允许异步检索元素的 IEnumerable 接口的异步版本。此接口用于与实体框架查询交互,不应由自定义类实现。

这是一个老问题,但它出现在 DbQuery 上的谷歌搜索中,所以只是为了更新一下:

在 EF Core 2.1 中,查询类型现在映射到 DbQuery 类型,如位于

https://learn.microsoft.com/en-us/ef/core/modeling/query-types

以下是相关位:

查询类型与实体类型有许多相似之处...

但是,它们与实体类型不同,因为它们:

  • 不需要定义键。

  • 永远不会跟踪 DbContext 上的更改,因此永远不会在数据库中插入、更新或删除。

  • 永远不会被惯例发现。

    • 仅支持导航映射功能的子集 - 具体而言:
    • 他们可能永远不会成为一段关系的主要目的。
    • 它们只能包含指向实体的引用导航属性。 实体不能包含查询类型的导航属性。
  • 在模型构建器上使用查询方法而不是实体方法进行寻址。

  • 通过 DbQuery 而不是 DbSet 类型的属性在 DbContext 上映射

  • 使用 ToView 方法(而不是 ToTable)映射到数据库对象。

  • 可以映射到定义查询 - 定义查询是在模型中声明的辅助查询,它充当查询类型的数据源。

您可以在 DbContext 中定义 QueryType,就像 DbSet 一样,但使用 DbQuery 类型:

public virtual DbQuery<CustomClassThatMapsYourQueryResults> QueryResults { get; set; }

然后在 OnModelCreate 方法中指示自定义结果对象映射到数据库中存储的过程:

modelBuilder.Query<CustomClassThatMapsYourQueryResults>();

然后在数据访问代码的某处:

var someVariable = 1;
var someOtherVariable = "someValue";
...
var myResults = _dbContext.FromSql($"spStoredProcName {someVariable} '{someOtherVariable}'"); 

我所知,填充 DbQuery对象的唯一方法是使用 FromSql() 方法。DbQuery FromSql() 方法的结果返回 IQueryable