我已经继承了一个遗留SQL数据库,我试图将其反向工程化为Code First。由于在当前配置上运行的传统软件,更改架构不是一个选项。对我来说奇怪的是,开发人员配置子表的复合主键由一个ChildId + ParentId组成,而不仅仅是ParentId。使用复合键的Code First Entity Framework 6:1到1
以下是我有:
public class Parent
{
public decimal PkParentId { get; set; }
public string ParentName { get; set; }
...
public Child Child { get; set; }
}
public class Child
{
public decimal PkChildId { get; set; }
public decimal PkParentId { get; set; }
public string ChildName { get; set; }
...
public Parent Parent { get; set; }
}
这里是我的映射。当我反向设计它时,EF想要在父母中创建一对一的孩子集合,但我真的想要1到0或1(一个孩子可能存在也可能不存在,但父母必须)。
public class ParentConfiguration : EntityTypeConfiguration<Parent>
{
public ParentConfiguration()
{
HasKey(p => p.PkParentId);
Property(p => p.PkParentId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasOptional(p => p.Child).WithRequired(p => p.Parent);
// Also tried this
// HasOptional(p => p.Child).WithRequired(p => p.Parent).Map(p => p.MapKey("PkParentId"));
}
}
public class ChildConfiguration : EntityTypeConfiguration<Child>
{
public ChildConfiguration()
{
// Pk is composite on child
HasKey(e => new {e.PkChildId, e.PkParentId});
Property(p => p.PkChildId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
我一起取父子没有问题,但如果我尝试插入一个家长和孩子:
var newParent = new Parent
{
ParentName = "XXX",
Child = new Child { ChildName = "YYY" }
};
_dbContext.Parents.Add(newParent);
_dbContext.SaveChanges();
这将导致以下错误:指定的列名“PkParentId”更多比SET子句中的一次。在同一个SET子句中,列不能分配多个值。修改SET子句以确保列只更新一次。如果SET子句更新视图的列,那么列名'PkParentId'可能在视图定义中出现两次。
果然,如果检查生成的SQL,它试图插入两次PkParentId插入子插入,一次作为第一个参数,一次作为最后一次。这就像EF没有放在一起,PkParentId是外键父导航属性,所以我试图将此添加到子配置:
HasRequired(x => x.Parent).WithOptional(y => y.Child).Map(z => z.MapKey("PkParentId"));
这会产生相同的错误。奇怪的是,我找不到一个可选的关系,它会让我使用除HasMore()之外的“HasForeignKey”强制我回到1:M。
谢谢,工作很好。无法告诉你在此之前我尝试了多少个排列组合。 –