如何在EF Core中获取对应数据库表的实体列表
如何在EF Core中仅获取对应数据库表的实体类型
在EF Core的派生DbContext中,重写OnModelCreating(ModelBuilder modelBuilder)方法时,调用modelBuilder.Model.GetEntityTypes()会返回模型中定义的所有实体类型。但如果实体包含复杂类型属性(属性类型为自定义类,而非字符串、数字等基础类型),这些作为属性的类也会被识别为实体并被该方法返回。我们需要的是仅获取那些对应数据库中实际表的实体类型。
复现步骤
- 创建C#控制台应用
- 添加以下NuGet包引用:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.3" />
- 将Program.cs替换为以下代码:
using System.Linq; using Microsoft.EntityFrameworkCore; public class Program { public static void Main(string[] args) { DbContextOptions<MyDbContext> options = new DbContextOptionsBuilder<MyDbContext>().UseNpgsql().Options; MyDbContext myDbContext = new(options); myDbContext.Database.EnsureCreated(); } } public class MyDbContext : DbContext { public DbSet<MyEntity> MyEntities { get; private set; } public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<MyEntity>().Property(e => e.StoreAsJson).HasColumnType("jsonb"); var entityTypes = modelBuilder.Model.GetEntityTypes().Where(et => !et.IsOwned()).ToList(); } } public class MyEntity { public string Id { get; set; } public StoreAsJson StoreAsJson { get; set; } } public class StoreAsJson { public string Id { get; set; } public string Value { get; set; } }
- 在
var entityTypes = modelBuilder.Model.GetEntityTypes().Where(et => !et.IsOwned()).ToList();行设置断点 - 运行程序,查看
entityTypes中的实体数量(会发现包含了StoreAsJson,但它并不对应数据库表)
可行解决方案
通过筛选DbContext中定义的DbSet<>对应的实体类型,可以精准获取对应数据库表的实体,代码如下:
HashSet<Type> entityClrTypes = typeof(MyDbContext).GetProperties() .Where(pi => pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)) .Select(pi => pi.PropertyType.GetGenericArguments()[0]) .ToHashSet(); List<IMutableEntityType> entityTypes = modelBuilder.Model.GetEntityTypes() .Where(et => entityClrTypes.Contains(et.ClrType)) .ToList();
注意:DbContext中的DbSet列表不一定和数据库中实际创建的表完全对应(比如有些实体可能通过Fluent API配置为不生成表,或者有表对应但没定义DbSet),但在匹配的业务场景中该方案有效。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

