Skip to main content
 首页 » 编程设计

c#之TPT 基类主键身份约定

2024年08月12日48jirigala

我首先使用代码,然后使用 TPT 继承。正在生成实体的基本类型表,但其主键上没有标识。 (如果有帮助,我可以发布代码)我的个人表有一个主键,但没有“是身份”。子类表按预期生成。

由于它没有为基本类型生成主键,我尝试将 HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) 添加到 Map,这破坏了模型,我收到一条错误消息:

Conflicting configuration settings were specified for property 'Id' on type 'Orion.Data.Entities.Person': DatabaseGeneratedOption = None conflicts with DatabaseGeneratedOption = Identity.

我已经搜索了可能为该属性指定“DatabaseGeneratedOption.None”的任何地方,但它不在我的代码中。我认为这是 EF6 中的配置约定。我试过调试 .net 以找出它的问题所在,但没有成功。

所以问题是,什么约定可能导致我可以禁用它?还是这里有其他事情在起作用?

编辑: 基础映射:

public abstract partial class Person 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; }  
} 
 
public class PersonMap : EntityTypeConfiguration<Person> 
{ 
    public PersonMap() 
    { 
        // Primary Key 
        this.HasKey(t => t.Id); 
 
        // Properties 
        this.Property(t => t.FirstName) 
            .IsRequired() 
            .HasMaxLength(25); 
 
        this.Property(t => t.LastName) 
            .IsRequired() 
            .HasMaxLength(25); 
 
        this.ToTable("People"); 
        this.Property(t => t.Id).HasColumnName("Id"); 
        //this.Property(t=>t.Id).HasColumnName("Id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) 
        this.Property(t => t.FirstName).HasColumnName("FirstName"); 
        this.Property(t => t.LastName).HasColumnName("LastName"); 
 
        // Relationship 
        this.HasOptional(x => x.User) 
            .WithRequired(x => x.Person).WillCascadeOnDelete(false); 
 
        this.HasMany(a => a.Addresses).WithOptional().WillCascadeOnDelete(true); 
    } 
} 

继承类:

public partial class ClientRep : Person 
{ 
    public ClientRep() 
    { 
        this.Jobs = new ObservableCollection<Job>(); 
    } 
    public int ClientId { get; set; } 
    public bool? IsPrimaryContact { get; set; } 
    public string JobContactType { get; set; } 
    public Client Client { get; set; } 
    public ICollection<Job> Jobs { get; set; } 
} 
public class ClientRepMap : EntityTypeConfiguration<ClientRep> 
{ 
    public ClientRepMap() 
    { 
        this.HasKey(t => t.Id); 
 
        this.Property(t => t.Id) 
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 
 
        this.ToTable("People_ClientRep"); 
        this.Property(t => t.ClientId).HasColumnName("ClientId"); 
        this.Property(t => t.IsPrimaryContact).HasColumnName("IsPrimaryContact"); 
        this.Property(t => t.JobContactType).HasColumnName("JobContactType"); 
        this.Property(t => t.Id).HasColumnName("Id"); 
 
        this.HasMany(t => t.Jobs) 
            .WithMany(t => t.ClientReps) 
            .Map(m => 
                { 
                    m.ToTable("JobClientRep"); 
                    m.MapLeftKey("ClientRep_Id"); 
                    m.MapRightKey("Job_Id"); 
                }); 
 
        this.HasRequired(t => t.Client) 
            .WithMany(t => t.ClientReps) 
            .HasForeignKey(d => d.ClientId).WillCascadeOnDelete(false); 
    } 
} 

然后在我的 DbContext 中:

public partial class ProgramDbContext : DbContext, IProgramDbContext 
{ 
    static OrionDbContext() 
    { 
        Database.SetInitializer(new OrionContextSeedInitializer()); 
    } 
    public OrionDbContext() 
        : base("ConnectionString") 
    { 
        this.Configuration.LazyLoadingEnabled = false; 
        this.Configuration.ProxyCreationEnabled = false; 
    } 
    //No DbSet for Person 
    public IDbSet<ClientRep> ClientRep { get; set; } 
    public IDbSet<ContactPerson> ContactPerson { get; set; } 
    public IDbSet<OtherPerson1> OtherPerson1{ get; set; } 
 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
        //modelBuilder.Conventions.AddBefore<StoreGeneratedIdentityKeyConvention>(new InheritanceKeyConvention()); 
        //modelBuilder.Conventions.Remove<StoreGeneratedIdentityKeyConvention>(); 
 
        //abridged 
        modelBuilder.Configurations.Add(new PersonMap()); 
        modelBuilder.Configurations.Add(new ClientRepMap()); 
        modelBuilder.Configurations.Add(new ContactPersonMap()); 
        modelBuilder.Configurations.Add(new OtherPerson1Map()); 
 
        //modelBuilder.Entity<Person>() 
        //    .Property(a => a.Id) 
        //    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
    } 

它似乎与 StoreGeneratedIdentityKeyConvention 有关 - 它似乎将身份分配给我的所有其他实体,但这个不明白......我认为这与它有关抽象类。我试图用以下方法覆盖该配置:

modelBuilder.Entity<Person>() 
.Property(a => a.Id) 
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

但还是有冲突。

请您参考如下方法:

好吧,那是 8 个小时的荒谬冒险!

背景:我首先通过对现有数据库进行逆向工程来导入代码。

这生成了我的继承实体,使其具有主键,但没有标识。我删除了所有到 Id 属性的映射,因为它不存在于继承的实体上,只存在于基础上。 (现在这一切都变得更有意义了……哎呀,真是浪费了一天!)

我继承的类和映射现在看起来像这样:

public partial class ClientRep : Person 
{ 
    public ClientRep() 
    { 
        this.Jobs = new ObservableCollection<Job>(); 
    } 
    public int ClientId { get; set; } 
    public bool? IsPrimaryContact { get; set; } 
    public string JobContactType { get; set; } 
    public Client Client { get; set; } 
    public ICollection<Job> Jobs { get; set; } 
} 
public class ClientRepMap : EntityTypeConfiguration<ClientRep> 
{ 
    public ClientRepMap() 
    { 
        this.ToTable("People_ClientRep"); 
        this.Property(t => t.ClientId).HasColumnName("ClientId"); 
        this.Property(t => t.IsPrimaryContact).HasColumnName("IsPrimaryContact"); 
        this.Property(t => t.JobContactType).HasColumnName("JobContactType"); 
        this.HasMany(t => t.Jobs) 
            .WithMany(t => t.ClientReps) 
            .Map(m => 
                { 
                    m.ToTable("JobClientRep"); 
                    m.MapLeftKey("ClientRep_Id"); 
                    m.MapRightKey("Job_Id"); 
                }); 
        this.HasRequired(t => t.Client) 
            .WithMany(t => t.ClientReps) 
            .HasForeignKey(d => d.ClientId).WillCascadeOnDelete(false); 
    } 
} 

一旦我从逆向工程中删除了这些残余物,一切都会按需生成。