【问题标题】:Whats the difference between IQueryable and DbQuery?IQueryable 和 DbQuery 有什么区别?
【发布时间】:2014-12-23 16:37:29
【问题描述】:

跟进这个问题/答案
How to make Entity Framework Data Context Readonly

解决方案是让 DbQuery 类型的 DbContext 集合,但这是一个相当特殊的类型(它被埋在 EF 的命名空间中)。

那么,有一个 DbContext 和这个有什么功能区别:

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

对比这个:

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

...当涉及到 DbQuery 类时,EF 文档非常简单,但我更喜欢让 DbContext 由接口而不是类组成的想法,所以我想避免它。 DbQuery 类提供了哪些额外的好处?

更新

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

【问题讨论】:

  • 你为什么不阅读源代码? IDbQuery&lt;T&gt; 只是有更多的方法...
  • 然后是 DbSet。

标签: c# .net entity-framework-5 datacontext


【解决方案1】:

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

IOrderedQueryable

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

IListSource 

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

IDbAsyncEnumerable

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

【讨论】:

  • 我假设您的意思是 [*] 异步扩展方法?这些似乎是唯一的区别 - 同意吗?
  • 如果您查看文档,您可以看到 Dbquey 还实现了其他接口。如果您不需要任何这些。不要使用它。除非您需要,否则请尽可能保持您的 api 干净
  • 如果您从另一个项目引用此属性,则使用 DbQuery 将要求另一个项目具有对实体框架的引用,而 IQueryable 无需该引用即可工作。
【解决方案2】:

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

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

的文档中所述

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

以下是相关位:

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

...

但它们与实体类型的不同之处在于:

  • 不需要定义键。

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

  • 按照惯例从未被发现。

    • 仅支持导航映射功能的一个子集 - 具体来说:
    • 他们可能永远不会充当关系的主要目的。
    • 它们只能包含指向实体的参考导航属性。 实体不能包含查询类型的导航属性。
  • 在 ModelBuilder 上使用 Query 方法而不是 Entity 方法进行寻址。

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

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

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

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

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

然后在您的 OnModelCreating 方法中表明您的自定义结果对象已映射到数据库中的存储过程:

modelBuilder.Query<CustomClassThatMapsYourQueryResults>();

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

var someVariable = 1;
var someOtherVariable = "someValue";

...

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 2011-12-12
    相关资源
    最近更新 更多