今天在編寫DomainModel和DomainMapper,最后放到OnModelCreating中運行的時候,給我拋出了如下錯誤:
One or more validation errors were detected during model generation: TinyFrame.Data.DataContext.t_expert_content_ExpertType: : Multiplicity conflicts with the referential constraint in Role 't_expert_content_ExpertType_Target' in relationship 't_expert_content_ExpertType'. Because all of the properties in the Dependent Role are non-nullable, multiplicity of the Principal Role must be '1'.
排查了一會兒找到了原因所在。
請看我的Model:
public class t_expert_content { public string ID { get; set; } //PK public string TypeID { get; set; } public string Name { get; set; } //問題標題 public string Publisher { get; set; } //發布人 public int? Count { get; set; } //查看次數 public bool IsCheck { get; set; } //是否審核 public DateTime PublishDate { get; set; } //發布時間 public string Content { get; set; } public int? Order { get; set; } public virtual t_expert_type ExpertType { get; set; } }
然后是ModelMapper:
public class t_expert_content_mapper : EntityTypeConfiguration<t_expert_content> { public t_expert_content_mapper() { this.ToTable("t_expert_content"); this.HasKey(x => x.ID); this.Property(x => x.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); this.Property(x => x.ID).HasMaxLength(36); this.Property(x => x.TypeID).IsRequired().HasMaxLength(36); this.Property(x => x.Name).IsRequired().HasMaxLength(500); this.Property(x => x.Publisher).IsOptional().HasMaxLength(150); this.Property(x => x.Count).IsOptional(); this.Property(x => x.IsCheck).IsRequired(); this.Property(x => x.PublishDate).IsRequired(); this.Property(x => x.Content).IsOptional().HasColumnType("text"); this.Property(x => x.Order).IsOptional(); this.HasOptional(x => x.ExpertType) .WithMany() .HasForeignKey(x => x.TypeID) .WillCascadeOnDelete(false); } }
看上去沒啥問題,但是問題就出在外鍵映射上面。
由於t_expert_content的外鍵TypeID 是t_expert_type表中的主鍵ID。由於我在映射的時候,寫的是:
this.Property(x => x.TypeID).IsRequired().HasMaxLength(36);
而在下面進行導航屬性指定的時候,ExpertType被指定成了HasOptional類型的:
this.HasOptional(x => x.ExpertType) .WithMany() .HasForeignKey(x => x.TypeID) .WillCascadeOnDelete(false);
導致二者產生了沖突,拋出了開頭的錯誤。
知道了原因,解決方法就好辦了:
public class t_expert_content_mapper : EntityTypeConfiguration<t_expert_content> { public t_expert_content_mapper() { this.ToTable("t_expert_content"); this.HasKey(x => x.ID); this.Property(x => x.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); this.Property(x => x.ID).HasMaxLength(36); //this.Property(x => x.TypeID).IsRequired().HasMaxLength(36); this.Property(x => x.Name).IsRequired().HasMaxLength(500); this.Property(x => x.Publisher).IsOptional().HasMaxLength(150); this.Property(x => x.Count).IsOptional(); this.Property(x => x.IsCheck).IsRequired(); this.Property(x => x.PublishDate).IsRequired(); this.Property(x => x.Content).IsOptional().HasColumnType("text"); this.Property(x => x.Order).IsOptional(); this.HasRequired(x => x.ExpertType) .WithMany() .HasForeignKey(x => x.TypeID) .WillCascadeOnDelete(false); } }
需要說明的是,上面代碼中的:
this.Property(x => x.TypeID).IsRequired().HasMaxLength(36);
可以選擇注釋,也可以選擇不注釋。