我们正在使用 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/