如何检查DBContext是否已释放?

gay*_*991 8 c# entity-framework asp.net-web-api entity-framework-6

我想与从外部(继承类)调用的另一个方法共享数据库上下文,而不创建新的上下文,除非正在释放它。我想检查上下文是否已处理,以便我可以创建新的上下文。

这是休息 API。有多个实体的批量上传,我想共享事务,因此如果一个实体失败,它将不会提交到数据库

Pet*_*ien 4

不管质疑设计质量的评论如何,如果 dbContext 可能处于已处置状态,则存在有效的场景,例如(不是完整列表):

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

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

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

性能考虑:最值得信赖的选项是在每个子级(api 调用/异步任务)上重新创建 dbContext,但这可能会产生不需要的性能开销,例如在处理 1000 次 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

使用分部类扩展 DbContext 或者将方法添加到现有的扩展分部类中。

仅供参考 - 如果仍在处理更新的 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

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

Run Code Online (Sandbox Code Playgroud)