何时在 DbContext 上执行查询

Posted

技术标签:

【中文标题】何时在 DbContext 上执行查询【英文标题】:When are queries executed on DbContext 【发布时间】:2017-10-31 12:18:42 【问题描述】:

我试图了解使用 EF6 框架时拥有一个 DbContext 类与多个 DbContext 类的性能影响。

例如,如果我们有一个像这样的简单 DbContext:

public class MainDbContext : DbContext

    public DbSet<Car> Cars  get; set; 

    public void AddCar(Car car)
    
        Cars.Add(car);
        SaveChanges();
    

现在假设我有一个服务,它以下列方式使用所述 DbContext:

public class CarService

    public List<Car> Cars  get; private set; 
    public CarService()
    
        var dbContext = new MainDbContext();
        Cars = dbContext.Cars.ToList();
    

DbContext 在什么时间点进入数据库并检索到存储在数据库中的所有汽车?是我打电话给var dbContext = new MainDbContext();的时候还是我打电话给Cars = dbContext.Cars.ToList();的时候?

如果是前者,如果我有一个包含 100 个表的 DbContext,那么在创建 DbContext 时会查询所有 100 个表吗?

【问题讨论】:

At what point in time did the DbContext go to the database and retrieved all cars that are stored in the database? 在那个代码中?绝不。它不起作用,DBContext 上的 Cars 属性应该是 DbSet&lt;Car&gt; 类型 即使是DbSet&lt;T&gt;,它也只会在您通过调用ToList() 之类的东西明确告知它时从数据库中获取数据。 Cars 本身不做任何事情 - 它是实体的容器,但它不会保存所有数据,除非你这样做。如果将IQueryable 与 Linq 一起使用,则只有在评估枚举数或通过上下文对底层连接执行 SQL 语句时才会提取数据。 【参考方案1】:

没有。一旦您枚举了一个表,查询就会发生。即使在您的第二个示例中,它仍然没有连接到数据库。

枚举的时候会连接,例如:

dbContext.Cars.ToList();

或者

foreach (Car c in dbContext.Cars)

或者将表格绑定到 UI 控件。

但是,当您创建位置时,按顺序,然后按,加入等...例如

var result = dbContext.Cars.Where(c => c.Id == 35).OrderBy(c => c.Name);

您将不会连接到数据库。您只是准备将操作的逻辑序列转换为 SQL 查询。


问题更新后

现在,您的第二个示例使用 ToList() 枚举结果并连接到数据库以获取数据。

【讨论】:

以上是关于何时在 DbContext 上执行查询的主要内容,如果未能解决你的问题,请参考以下文章

原始 SQL 查询和实体框架核心

EF7DbContext池

WPF 何时决定重新查询命令是不是可以执行?

OpenJPA 查询何时执行以及啥是顺序

如何从 EF7 DbContext 获取 ConnectionString

实体框架 ChangeTracker 流并保存到查询