EF6 Code First复合主键和外键:必须映射外键

时间:2016-04-12 18:06:49

标签: foreign-keys entity-framework-6 entity ef-fluent-api ef-model-builder

好吧,经过一个早上的头撞墙后,我把它扔到那里。

我有一个DB表(Table1),带有复合PK(Column1,Column2,Column3)。 (Column1,Column3)也是另一个表的FK(表2)。

尝试使用Code First EF6(6.1.3),这是模型:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetFileInformationByHandle(SafeFileHandle hFile, out BY_HANDLE_FILE_INFORMATION lpFileInformation);

我的modelBuilder(Fluent API):

[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; }
}

也许我错过了Object2中的ICollection?

我收到一条错误,上面写着“从表Object1(Column1,Column3)到表Object2(Column1,Column3)的外键约束::映射不足:外键必须映射到一些参与外部的AssociationSet或EntitySets概念方面的关键关联。“

我试过了:

modelBuilder.Entity<Object1>()
    .HasRequired(o => o.SecondObject)
    .WithMany()
    .HasForeignKey(o => new { o.Column1, o.Column3 });

无济于事。我得到了“在Object2上声明的FirstObjects配置了冲突的外键”错误。

这是从现有数据库生成的CodeFirst。

1 个答案:

答案 0 :(得分:0)

很快,你的第一个流畅的配置

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 });

但请确保从新数据库或无数据库开始,因为自动迁移无法正确处理该更改。如果您想保留数据库,请注释掉任何Object1Object2配置代码以及相应的DbSet。然后更新数据库。 (确保Table1Table2被删除)。然后取消注释Object1Object2相关代码(使用第二个配置!)并更新数据库。现在一切都应该没问题。我在一个干净的环境中做到了它并且有效。