在 Repository 中使用时 DbContext 何时被垃圾收集或处置?

when DbContext is garbage-collected or disposed when using in Repository?

我已经实现了存储库模式,并且在存储库中,我在构造函数中添加了 dbContext,如下所示。使用static是有原因的。我研究的时候,不建议在Context中使用static。 我理解其中的大部分,但是当上下文被处理时我没有理解,就好像我把它当作静态的一样,它不是由垃圾收集器处理的。那么什么时候处理呢? HTTP 请求何时完成? 还是在应用程序关闭之前它还活着?

private static DBContext _context;
public OrderRepository(DbContext context)
{
    _context = context;
}

静态对象将一直存在到程序结束。

但是,您应该担心的不是静态部分,而是 IDispose 部分。

您的 DbContext 在您的程序结束之前不会被释放。这是否是一个问题,取决于其他人是否会连接到数据库,以及您的程序会持续多长时间 运行.

如果您的程序只有 运行 几秒钟,那么如果数据库连接在这几秒钟内保持活动状态就不会成为大问题。

不过请注意,除了数据库连接之外,还有一个 ChangeTracker。

每当您查询完整的实体(=完整的 table 行)时,原始值和获取项目的副本将被放入 ChangeTracker。您将获得对此副本的引用。每当您更改所获取项目的属性值时,这些更改将出现在 ChangeTracker 中的副本中。

当您调用 SaveChanges 时,会将副本与原始文件进行比较以确定必须更新哪些 属性 个值。

如果您让 DbContext 保持活动状态很长一段时间,并且您获取了很多项目,那么您将拥有一个填充了很多项目的 ChangeTracker。

此外,如果您使用Find通过主键获取项目,那么DbContext将首先检查该项目是否已经在ChangeTracker中。

所以除了ChangeTracker的庞大内容导致的性能问题,你也不会获取到最新的数据库值。

如果别人更新了一个Customer而你获取了同一个Customer,那么这取决于你是否已经在几个小时前获取了这个Customer,你获取的是哪个Customer:你获取的旧的未更新的Customer在客户更新之前,或者新更新的客户,因为你还没有获取这个客户?您确定要跟踪自启动程序以来您获取了哪些客户吗?如果你不这样做,你将永远不知道你得到的是几个小时前获取的客户,还是最新更新的版本。

这些问题已经够多了,可以通过让 DbContext 保持尽可能短的活动时间来轻松缓解这些问题。添加第二次创建 DbContext 对象相当便宜的论点,我相信您不应该让 DbContext 对象保持比需要更长的时间。

public Customer AddCustomer(...)
{
    using (var dbContext = new MyDbContext())     // or use a factory
    {
        Customer addedCustomer =  dbContext.Customers.Add(...);
        dbContext.SaveChanges();
        return addedCustomer;
    }
}

public ICollection<Customer> QueryCustomerByCity(int CityId)
{
    using (var dbContext = new MyDbContext()) 
    {
        return dbContext.Customers
            .Where(customer => customer.CityId == cityId)
            .ToList();
    }
}

等等