什么是IQueryable和DbQuery之间的区别?

时间:2014-12-23 16:37:30

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

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

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

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

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

vs this:

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

...当谈到DbQuery类时,EF文档很轻松,但我更喜欢让DbContext由接口而不是类组成,所以我想避免使用它。 DbQuery类提供了哪些额外的好处?

更新

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

2 个答案:

答案 0 :(得分:3)

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

IOrderedQueryable

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

IListSource 

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

IDbAsyncEnumerable

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

答案 1 :(得分:1)

这是一个古老的问题,但它出现在DbQuery的google搜索中,因此只需要进行一些更新即可:

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

的文档中所述

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

以下是相关位:

  

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

     

...

     

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

     
      
  • 不需要定义密钥。

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

  •   
  • 从未被惯例发现。

         
        
    • 仅支持部分导航映射功能-具体来说:
    •   
    • 他们可能永远不会成为恋爱关系的主要目的。
    •   
    • 它们只能包含指向实体的参考导航属性。   实体不能包含用于查询类型的导航属性。
    •   
  •   
  • 使用Query方法而不是Entity方法在ModelBuilder上解决。

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

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

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

  •   

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

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

然后在OnModelCreating方法中,指示您的自定义结果对象已映射到数据库中存储的proc:

modelBuilder.Query<CustomClassThatMapsYourQueryResults>();

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

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

...

var myResults = _dbContext.FromSql($"spStoredProcName {someVariable} '{someOtherVariable}'"); 
据我所知,填充DbQuery 对象的唯一方法是使用FromSql()方法。 FromSql()方法的DbQuery 结果返回IQueryable