c# - 处置 DbContext 创建的实体对象

标签 c# .net-core entity-framework-core npgsql

我们正在使用 EF Core 和 Postgres Npgsql 提供程序实现 DAL。

一些表具有 jsonb 列,我们将它们映射到实体对象中的 JsonDocument 属性。

页面JSON Mapping在 Npgsql 文档中有以下注释:

Note also that JsonDocument is disposable, so the entity type is made disposable as well; not dispose the JsonDocument will result in the memory not being returned to the pool, which will increase GC impact across various parts of the framework.

根据文档,我们已将这些实体设为一次性:

public class SomeEntity : IDisposable
{
    public int Id { get; set; }

    public JsonDocument JsonData { get; set; }

    public void Dispose()
    {
        JsonData?.Dispose();
    }
}

问题在于,在正确处置 DbContext 时,永远不会调用实体对象的 Dispose 方法。我们看到的唯一方法是在处置 DbContext 时手动枚举 DbSet 并为每个实体调用 Dispose 方法:

public class SomeDbContext : DbContext
{
    public DbSet<SomeEntity> SomeEntities { get; set; }

    private bool DisposedEntities { get; set; }

    public override void Dispose()
    {
        DisposeEntities();

        base.Dispose();
    }

    public override ValueTask DisposeAsync()
    {
        DisposeEntities();

        return base.DisposeAsync();
    }

    private void DisposeEntities()
    {
        if (DisposedEntities)
        {
            return;
        }

        DisposeEntities(SomeEntities);

        DisposedEntities = true;
    }

    private static void DisposeEntities<TEntity>(IEnumerable<TEntity> dbSet)
        where TEntity : IDisposable
    {
        foreach (var entity in dbSet)
        {
            entity.Dispose();
        }
    }
}

有没有办法在处置 DbContext 时强制 EF Core 处置实体?

上述手动实体处理方法是否正常或者有一些缺陷?

最佳答案

不行。您的实现在处置期间加载整个表,因为在枚举 DbSet 时 - 它从数据库加载数据。

考虑更改函数签名并从 Local 集合中处置实体:

private static void DisposeEntities<T>(DbSet<T> dbSet) 
    where T : class, IDisposable
{
    foreach (var entity in dbSet.Local)
    {
        entity.Dispose();
    }
}

关于c# - 处置 DbContext 创建的实体对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72827413/

相关文章:

javascript - C# 如何在静态Web方法中获取asp.net文本框值?

c# - Azure Function,EF Core,无法加载 ComponentModel.Annotations 4.2.0.0

c# - 类型 'IEnumerable<>' 在未引用的程序集中定义。系统.运行时

c# - Wpf组合框通过鼠标选择项目

c# - HttpClient.GetAsync 立即抛出 TaskCanceledException

c# - 在 Windows 8 商店 C# 应用程序 : The base class or interface could not be resolved 中使用 WSDL Web 服务

c# - .NET Core SDK 的错误 : Version 5. 0.10 0-alpha1-014696 需要至少版本 16.3.0 的 MSBuild

c# - 如何在 C# 中获取 PSObject.Properties 的 ScriptProperty 值?

redis - 尝试将 : Changing . NET 标准库的依赖项解析为 NET Core - Microsoft.Extensions.Primitives

c# - 为什么 "IQueryable.Where()"在此查询中提供与 "IEnumerable.Where()"不同的结果?