MVC出错案例之一:主外键映射失败

今天在编写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);

可以选择注释,也可以选择不注释。

上一篇:HTTP响应代码


下一篇:[转]Oracle查询树形数据的叶节点和子节点