You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET6 EF枚举DbSet遇InvalidOperationException问题及优化咨询

.NET6 EF Core DbContext动态枚举DbSet的问题与优化

一、原异常问题及修复方案

异常原因

原代码循环枚举DbSet并调用dbSet.Load()时,第一个DbSet的DataReader未关闭,第二个DbSet操作复用同一数据库连接时,触发System.InvalidOperationException(提示「已有打开的DataReader关联当前连接,需先关闭」)。

修复方案

方案1:启用多活动结果集(MARS)

在数据库连接字符串中添加MultipleActiveResultSets=True,允许同一连接同时处理多个DataReader:

Server=.;Database=YourDb;Trusted_Connection=True;MultipleActiveResultSets=True;

方案2:优化记录数获取逻辑(推荐)

无需加载所有实体到内存,直接通过EF Core的Count()查询获取记录数,避免保持DataReader打开,同时提升性能:

public static IEnumerable<EntityInfo> GetEntitiesInfo(this MyDbContext context)
{
    var dbSetProperties = context.GetDbSetProperties();
    var index = 0;
    foreach (var property in dbSetProperties)
    {
        ++index;
        var dbSet = property.GetValue(context, null) as IQueryable;
        var count = dbSet?.Cast<object>().Count() ?? 0;
        yield return new EntityInfo(index, dbSet?.ElementType?.ToString(), count);
    }
}

二、更新代码的简化优化

你当前的简化代码已足够简洁,可进一步优化类型判断逻辑,避免依赖字符串匹配(更可靠):

public static IEnumerable<IQueryable<object>> GetDbSets(this MyDbContext context)
{
    return context.GetType()
        .GetRuntimeProperties()
        .Where(p => p.PropertyType.IsGenericType 
            && p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
        .Select(p => (IQueryable<object>)p.GetValue(context, null));
}

直接通过泛型类型定义判断,比字符串匹配更准确,避免因命名空间变化导致的判断失效。

三、其他枚举DbSet的方式

除了反射属性,还可以通过EF Core的元数据系统获取,无需依赖反射匹配属性:

public static IEnumerable<IQueryable<object>> GetDbSets(this DbContext context)
{
    foreach (var entityType in context.Model.GetEntityTypes())
    {
        yield return context.Set(entityType.ClrType) as IQueryable<object>;
    }
}

这种方式直接从EF Core的模型元数据中获取所有实体类型,再通过context.Set(Type)获取对应的DbSet,更符合EF Core的设计,也能覆盖所有映射的实体(包括未通过DbSet属性暴露的实体)。

内容的提问来源于stack exchange,提问作者ShamilS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:26:07