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

EF Core:如何让所有生成的迁移包含通用列?

解决方案

问题根源

你之前为抽象基类Entity创建了IEntityTypeConfiguration<Entity>,这会让EF将Entity视为实体类型,即使它是抽象的,仍会生成Entities表存储基类属性;同时TPT架构下子类属性会单独存放在子类表,通过外键关联基类表,导致Key列只在基类表中,不符合需求。

实现方案(VB.NET)

1. 基类与实体类

Public MustInherit Class Entity
    Public Property Id As Integer
    Public Property Key As Guid
End Class

Public Class City
    Inherits Entity
    Public Property Name As String ' 修正原代码中Name的类型错误
    Public Property Code As String
End Class

2. DbContext配置

Imports Microsoft.EntityFrameworkCore
Imports System.Linq

Public Class AppDbContext
    Inherits DbContext

    ' 仅注册具体实体的DbSet,不要添加DbSet(Of Entity)
    Public Property Cities As DbSet(Of City)

    Protected Overrides Sub OnConfiguring(optionsBuilder As DbContextOptionsBuilder)
        optionsBuilder.UseSqlServer("你的数据库连接字符串")
    End Sub

    Protected Overrides Sub OnModelCreating(modelBuilder As ModelBuilder)
        MyBase.OnModelCreating(modelBuilder)

        ' 遍历所有继承自Entity的具体实体,统一配置Key列的默认值
        For Each entityType In modelBuilder.Model.GetEntityTypes() _
            .Where(Function(t) t.ClrType.IsSubclassOf(GetType(Entity)) AndAlso Not t.ClrType.IsAbstract)

            modelBuilder.Entity(entityType.ClrType) _
                .Property(Of Guid)("Key") _
                .IsRequired() _
                .HasDefaultValueSql("NEWID()")
        Next

        ' 应用具体实体的表配置
        modelBuilder.ApplyConfiguration(New CityConfiguration())
    End Sub
End Class

3. 实体表配置

Imports Microsoft.EntityFrameworkCore
Imports Microsoft.EntityFrameworkCore.Metadata.Builders

Public Class CityConfiguration
    Implements IEntityTypeConfiguration(Of City)

    Public Sub Configure(builder As EntityTypeBuilder(Of City)) Implements IEntityTypeConfiguration(Of City).Configure
        ' 指定实体对应的表名
        builder.ToTable("Cities")

        ' 可在此配置当前实体的专属属性规则
        builder.Property(Function(c) c.Name).HasMaxLength(100).IsRequired()
        builder.Property(Function(c) c.Code).HasMaxLength(10).IsRequired()
    End Sub
End Class

实现方案(C#)

1. 基类与实体类

public abstract class Entity
{
    public int Id { get; set; }
    public Guid Key { get; set; }
}

public class City : Entity
{
    public string Name { get; set; }
    public string Code { get; set; }
}

2. DbContext配置

using Microsoft.EntityFrameworkCore;
using System.Linq;

public class AppDbContext : DbContext
{
    public DbSet<City> Cities { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("你的数据库连接字符串");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // 遍历所有继承自Entity的具体实体,统一配置Key列的默认值
        foreach (var entityType in modelBuilder.Model.GetEntityTypes()
            .Where(t => t.ClrType.IsSubclassOf(typeof(Entity)) && !t.ClrType.IsAbstract))
        {
            modelBuilder.Entity(entityType.ClrType)
                .Property<Guid>("Key")
                .IsRequired()
                .HasDefaultValueSql("NEWID()");
        }

        modelBuilder.ApplyConfiguration(new CityConfiguration());
    }
}

3. 实体表配置

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

public class CityConfiguration : IEntityTypeConfiguration<City>
{
    public void Configure(EntityTypeBuilder<City> builder)
    {
        builder.ToTable("Cities");

        builder.Property(c => c.Name).HasMaxLength(100).IsRequired();
        builder.Property(c => c.Code).HasMaxLength(10).IsRequired();
    }
}

方案优势

  • 不会生成Entities基类表,所有具体实体都有独立的表
  • 统一配置Key列的默认值,避免重复代码
  • 每个实体表会自动包含基类的Id和Key属性,满足需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:40:23