好吧,在一个早上我的头撞在墙上之后,我把这个扔出去了。
我有一个DB表(表1)和一个复合PK(第1列,第2列,第3列)。(第1列,第3列)也是另一个表(表2)的FK。
尝试使用Code First EF6(6.1.3),以下是模型:
[Table("DB.Table1")]
public partial class Object1
{
[Key]
[Column(Order=0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Column1 { get; set; }
[Key]
[Column(Order=1)]
public byte Column2 { get; set; }
[Key]
[Column(Order=2)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Column3 { get; set; }
public virtual Object2 SecondObject { get; set; }
}
[Table("DB.Table2")]
public partial class Object2
{
public Object2()
{
FirstObjects = new HashSet<Object1>();
}
[Key]
[Column(Order=0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Column1 { get; set; }
[Key]
[Column(Order=1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Column3 { get; set; }
public virtual ICollection<Object1> FirstObjects { get; set; }
}
我的模型生成器(Fluent API):
modelBuilder.Entity<Object1>()
.HasRequired(o => o.SecondObject)
.WithMany()
.HasForeignKey(o => new { o.Column1, o.Column3 });
也许我在Object2中的ICollection中遗漏了什么?
我收到一个错误,上面写着"从表Object1(第1列,第3列)到表Object2(第1排,第3栏)的外键约束::映射不足:外键必须映射到概念上参与外键关联的一些AssociationSet或EntitySet。"
我试过了:
modelBuilder.Entity<Object1>()
.HasRequired(o => o.SecondObject)
.WithMany(o => o.FirstObjects)
.HasForeignKey(o => new { o.Column1, o.Column3 });
但无济于事。我得到一个"在Object2上声明的FirstObjects已配置有冲突的外键"错误。
这是从现有数据库生成的CodeFirst。
很快,您的第一个流畅的配置
modelBuilder.Entity<Object1>()
.HasRequired(o => o.SecondObject)
.WithMany()
.HasForeignKey(o => new { o.Column1, o.Column3 });
与Object2.FirstObjects
导航属性一起创建两个附加列和两只外键,这是不正确的,会导致问题。
这种型号的正确配置是第二种:
modelBuilder.Entity<Object1>()
.HasRequired(o => o.SecondObject)
.WithMany(o => o.FirstObjects)
.HasForeignKey(o => new { o.Column1, o.Column3 });
但请确保从新数据库或不使用数据库开始,因为自动迁移无法正确处理更改。如果要保留数据库,请注释掉任何Object1
或Object2
配置代码以及相应的DbSet
。然后更新数据库。(确保删除Table1
和Table2
)。然后取消注释与Object1
和Object2
相关的代码(使用第二个配置!)并更新数据库。现在一切都应该好起来了。我是在一个干净的环境里做的,而且效果很好。