Entity framework core 如何删除EF核心代码优先约定PK

Entity framework core 如何删除EF核心代码优先约定PK,entity-framework-core,ef-code-first,Entity Framework Core,Ef Code First,my(EF Core 3.1)模型中的许多实体都源自相同的基本类型(HistorizedBaseEntity),因此应该具有相同的主键: {int-ID,Guid-InstanceGuid,Instant-Time} 我没有按实体类型重新定义,而是编写了一些代码来自动处理此问题: protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder);

my(EF Core 3.1)模型中的许多实体都源自相同的基本类型(
HistorizedBaseEntity
),因此应该具有相同的主键:
{int-ID,Guid-InstanceGuid,Instant-Time}

我没有按实体类型重新定义,而是编写了一些代码来自动处理此问题:

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

    foreach (var mutableEntityType in modelBuilder.Model.GetEntityTypes().ToList()) 
    {
        if (mutableEntityType.ClrType.IsSubclassOf(typeof(BaseEntity)) 
            && mutableEntityType.BaseType == null)
        {
            var mutableKeys = mutableEntityType.GetKeys().ToList();
            foreach (var mutableKey in mutableKeys)
            {
                if (mutableKey.IsPrimaryKey() && mutableKey.Properties.Count == 1 
                                                && mutableKey.Properties.First().Name == nameof(IHasId.Id))
                    mutableEntityType.RemoveKey(mutableKey);
            }
    
            if (mutableEntityType.ClrType.IsSubclassOf(typeof(HistorizedBaseEntity)) 
                && mutableEntityType.BaseType == null)
            {
                if (!mutableKeys.Any(m => m.Properties.Select(p => p.Name)
                    .ToHashSet().SetEquals(HistorizedBaseEntity.PrimaryKeyNames)))
                {
                    var keyProperties = mutableEntityType.GetProperties()
                        .Where(p => HistorizedBaseEntity.PrimaryKeyNames.Contains(p.Name)).ToList();
                    mutableEntityType.SetPrimaryKey(keyProperties);
                }
            }
        }
    }
}
历史数据库实体:

    public class HistorizedBaseEntity 
    {
        public int Id { get; set; }
        public Guid InstanceGuid { get; set; }
        public Instant Time { get; set; }

        public static IReadOnlyList<string> PrimaryKeyNames =>
            new List<string> {nameof(Id), nameof(InstanceGuid), nameof(Time)}.AsReadOnly();

    }
公共类历史数据库实体
{
公共int Id{get;set;}
公共Guid实例Guid{get;set;}
公共即时时间{get;set;}
公共静态IReadOnlyList PrimaryKeyNames=>
新列表{nameof(Id)、nameof(InstanceGuid)、nameof(Time)}.AsReadOnly();
}
如果没有上述代码,所有从HistorizedBaseEntity派生的实体都有一个约定PK,其中“ID”作为字段

在上面的代码运行之后,我有两个密钥,基于约定的一个作为PK,新创建的一个作为唯一密钥。 从调试中,我看到RemoveKey()实际上删除了PK,然后在ConventionDispatcher.OnKeyRemoved中运行KeyDiscoveryConvention,将其添加回


如何在不禁用约定的情况下删除基于约定的PKs?

我测试了代码。它没有给我带
Id
的主键,而是一个复合主键和一个带
Id
的备用键。