如何使用复合主键创建复合外键 [英] How create composite foreign key to table with composite primary key

查看:269
本文介绍了如何使用复合主键创建复合外键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个复合主键表:

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

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

}

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

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

public virtual ICollection< Event>活动{get;组; }
}

我需要在上创建一个复合外键事件表到 EventDocument



我试图创建这样的FK



class事件:

  [ForeignKey (DocID1)] 
[列(Order = 0)]
public string DocID1 {get;组;

[ForeignKey(DocID2)]
[列(Order = 1)]
public string DocID2 {get;组;

但是我收到一个错误:


属性DocID1不能配置为导航属性。该属性必须是有效的实体类型,该属性应具有非抽象的getter和setter。对于集合属性,类型必须实现ICollection,其中T是有效的实体类型。}


我不明白我是什么做错了

解决方案

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


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


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

  [ForeignKey(DocID1,DocID2)] 
public virtual ICollection< Event>活动{get;组;

并且问题应该解决。



但是我个人觉得与Fluent API建立关系更容易理解,并且容易出错。例如,可以通过以下流畅的配置来实现:

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

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

 .HasKey(e => new {e.ID1,e.ID2}); 

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


I have two tables with composite primary keys:

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

I need to create a composite foreign key on Event table to EventDocument table

I've tried to create FK like this

class Event:

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

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

But I get an error:

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."}

I don't understand anymore what I am doing wrong

解决方案

Composite foreign key requires ForeignKey attribute to be applied on the navigation property specifying the comma separated list of the foreign key property names:

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.

Since you have no navigation property in the Event class, you should apply it on the corresponding navigation property in the EventDocument class:

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

and the issue should be resolved.

But I personally find setting up relationships with Fluent API to be much easier to understand and less error prone. For instance, the same can be achieved by the following fluent configuration:

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

Same btw for the composite PKs (instead of all these Key / Column(Order = ...) attributes):

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

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

这篇关于如何使用复合主键创建复合外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆