如何使用复合主键为表创建复合外键

时间:2017-03-02 13:22:49

标签: entity-framework-6 foreign-keys code-first

我有两个包含复合主键的表:

public class Event
{
    [Key]
    [Column(Order = 1)]
    public string ID1 { get; set; }

    [Key]
    [Column(Order = 2)]
    public int ID2 { get; set; }
    public DateTime EventDate { get; set; }
    public string DocID1 { get; set; }
    public int DocID2 { get; set; }

}

public class EventDocument
{
    [Key]
    [Column(Order = 1)]
    public string ID1 { get; set; }
    [Key]
    [Column(Order = 2)]
    public int ID2 { get; set; }

    public string Name { get; set; }
    public string SurName { get; set; }
    public string Number { get; set; }

    public virtual ICollection<Event> Events { get; set; }
}

我需要在Event表到EventDocument

上创建一个复合外键

我试图像这样创建FK

课程活动:

[ForeignKey("DocID1")]
[Column(Order = 0)]
public string DocID1 { get; set; }

[ForeignKey("DocID2")]
[Column(Order = 1)]
public string DocID2 { get; set; }

但是我收到了一个错误:

  

属性&#39; DocID1&#39;无法配置为导航属性。该属性必须是有效的实体类型,并且该属性应具有非抽象的getter和setter。对于集合属性,类型必须实现ICollection,其中T是有效的实体类型。&#34;}

我不再理解我做错了什么

1 个答案:

答案 0 :(得分:5)

复合外键需要在导航属性上应用ForeignKey属性,并指定外键属性名称的逗号分隔列表:

  

如果将 ForeignKey 属性添加到外键属性,则应指定关联导航属性的名称。如果将 ForeignKey 属性添加到导航属性,则应指定关联外键的名称。如果导航属性具有多个外键,请使用逗号分隔外键名称列表。

由于Event类中没有导航属性,因此应将其应用于EventDocument类中相应的导航属性:

[ForeignKey("DocID1, DocID2")]
public virtual ICollection<Event> Events { get; set; }

问题应该解决。

但我个人认为与Fluent API建立关系更容易理解,更不容易出错。例如,通过以下流畅的配置可以实现相同的目的:

modelBuilder.Entity<EventDocument>()
    .HasMany(e => e.Events)
    .WithRequired() // or .WithOptional()
    .HasForeignKey(e => new { e.DocID1, e.DocID2 });

复合PK的btw相同(而不是所有这些Key / Column(Order = ...)属性):

modelBuilder.Entity<Event>()
    .HasKey(e => new { e.ID1, e.ID2 });

modelBuilder.Entity<EventDocument>()
    .HasKey(e => new { e.ID1, e.ID2 });