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是更好的选择。感谢您的耐心等待!
> 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