如何检查DBContext是否已被释放?

7
我希望能在不创建新上下文的情况下与从外部调用(继承类)的另一个方法共享DB上下文,除非该上下文被处置。我需要检查上下文是否已被处置,以便我可以创建新的上下文。
这是一个rest api。有多个实体的批量上传,我想要共享事务,以便如果其中一个失败,它将不会提交到DB。

1
即使您进行检查,在您使用它之间,它可能会被处理。我建议不要分享上下文。 - mjwills
@mjwills 这是一个 REST API。它支持多个实体的批量上传,我想共享事务,以便如果其中一个失败,它不会提交到数据库。 - gayan1991
你使用的是哪个IoC容器? - mjwills
1
您无需检查它是否已被处理,因为如果您的DbContext是由DI系统注入的,则您永远不需要自己处理它,因为它只会在控制器的生命周期结束时(即在操作完成之后但在视图呈现之前)被处理。请注意,您永远不应该从控制器操作中返回“打开”的IQueryable<T> - Dai
1
从你写的内容中并不清楚为什么需要处理上下文。批量上传意味着你已经拥有了所有数据,因此你只需创建一个事务并将其全部放入其中,如果出现任何问题则回滚。 - Andrei Dragotoniu
显示剩余4条评论
1个回答

2

不管有人对设计质量提出质疑,都存在一些情况下dbContext可能处于已释放状态,例如(不完整列表):

例如(在注入的dbContext MVC服务中):

  1. 您的服务通过一个或多个服务调用迭代,可能在较低层使用异步套接字处理程序和较低层API库,每个响应都使用父请求者dbContext。
  2. 您的服务调用数据库作业(异步任务或非异步任务)。
  3. 异常处理记录到数据库(如果dbContext已丢失-避免丢失调试详细信息)

注意:像这样使用dbContext的长时间运行过程应遵循避免dbContext膨胀的良好实践,例如尽可能使用AsNoTracking()方法-因为膨胀可能很快成为一个问题。

性能考虑: 最可靠的选项是在每个子级(api调用/异步任务)上重新创建dbContext,但这可能会产生不必要的性能开销,例如当处理数千个api迭代调用且原子单元事务不可行时。

使用框架测试的解决方案: 实体类型:Microsoft.EntityFrameworkCore.DbContext Version=5.0.16.0, Culture=neutral, PublicKeyToken=adb9793829ddae60

警告: 在使用这种扩展dbContext的方法时有很多警告建议,应该谨慎使用/尽可能避免使用。 详细警告请参见:c-sharp-working-with-entity-framework-in-a-multi-threaded-server

用partial class扩展您的DbContext或将方法添加到您现有的扩展partial class中。

注意:如果仍在使用更新的EntityFrameworkCore库,请评论说明。

public partial class FooDbContext : DbContext
{

    // Using Type: 5.0.16.0  EntityFrameworkCore.DbContext (confirm if working with any core library upgrades)
    
    public bool IsDisposed()
    {
        bool result = true;            
        var typeDbContext = typeof(DbContext);
        var isDisposedTypeField = typeDbContext.GetField("_disposed", BindingFlags.NonPublic | BindingFlags.Instance);

        if (isDisposedTypeField != null)
        {
            result = (bool)isDisposedTypeField.GetValue(this);
        }

        return result;
    }
}

使用方法:

if (fooDbContext == null || fooDbContext.IsDisposed())
{
    // Recreate context
}


1
经过测试,使用了AspNetCore 7.0.9库仍然可以正常工作,尽管这不是我可以使用的内容,但我花了一些时间来测试它。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接