如何使用复合主键创建 table 的复合外键

How create composite foreign key to table with composite primary key

我有两个 table 具有复合主键:

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 table 到 EventDocument table

上创建复合外键

我试过像这样创建 FK

class 事件:

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

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

但是我得到一个错误:

The property 'DocID1' cannot be configured as a navigation property. The property must be a valid entity type and the property should have a non-abstract getter and setter. For collection properties the type must implement ICollection where T is a valid entity type."}

我不明白我做错了什么

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

If you add the ForeignKey attribute to a foreign key property, you should specify the name of the associated navigation property. If you add the ForeignKey attribute to a navigation property, you should specify the name of the associated foreign key(s). If a navigation property has multiple foreign keys, use comma to separate the list of foreign key names.

由于你在Eventclass中没有导航属性,你应该在EventDocument[=]中相应的导航属性上应用它class:

[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 的顺便说一句(而不是所有这些 Key / Column(Order = ...) 属性):

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

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