【问题标题】:CodeFirst Foreign Key to two properties两个属性的 CodeFirst 外键
【发布时间】:2018-02-19 12:31:29
【问题描述】:

我想将一个属性用作两个单独实体的外键 - 一次作为复合外键的一部分,一次作为单个外键。这是我的意思的一个简单示例:

public class ParentEntity{
    [Key, Column(Order = 1)]
    String Id {get; set;}
    [Key, Column(Order = 2), ForeignKey("Year")]
    int YearId {get; set;}

    [ForeignKey("YearId")]
    Year Year;
    virtual ICollection<ChildEntity> Children {get; set;}
}

public class ChildEntity{
    [Key, Column(Order = 0), ForeignKey("Parent")]
    String Id {get; set;}
    [Key, Column(Order = 1), ForeignKey("Parent")]
    String ParentId {get; set;}
    [Key, Column(Order = 2), ForeignKey("Parent, Year")]
    int YearId {get; set;}

    [ForeignKey("ParentId, YearId")]
    ParentEntity Parent{get; set;}

    [ForeignKey("YearId")]
    Year Year {get; set;}
}

public class Year{
    [Key]
    int YearId {get; set;}
}

ChildEntity 中的 YearId/Year 属性应作为ParentEntity 的主键(ParentId / Year)的一部分,并作为Year 表的外键。

但是,标签ForeignKey("Parent, Year") 无效,因为它只能将一个参数传递给导航属性。这是我收到的错误消息:

Additional information: The ForeignKeyAttribute on property 'YearId' on type 'CodeFirst.Models.ChildEntity' is not valid. 
The navigation property 'Parent, Year' was not found on the dependent type 'CodeFirst.Models.ChildEntity'. 
The Name value should be a valid navigation property name.

我认为这是有道理的,它正在寻找一个名为“Parent,Year”的导航属性,而不是两个导航属性,分别名为“Parent”和“Year”。

如何强制 EntityFramework/CodeFirst 正确识别此模式?

注意:我将实体命名为“父”/“子”,但它们之间没有继承关系(实际上是所有权关系)。

【问题讨论】:

  • 只是不要使用复合键。这是一种反模式,会使您的代码变得不必要地复杂,没有目的。主键的全部意义在于它是唯一的。没有必要将它与其他任何东西结合起来。

标签: asp.net asp.net-mvc entity-framework code-first


【解决方案1】:
public class ParentEntity{
    [Key, Column(Order = 1)]
    String Id {get; set;}
    [Column(Order = 2)]
    int YearId {get; set;}

    [ForeignKey("YearId")]
    virtual Year Year;
    virtual ICollection<ChildEntity> Children {get; set;}
}

public class ChildEntity{
    [Key, Column(Order = 0)]
    String Id {get; set;} 
    String ParentId {get; set;}
    int YearId {get; set;}
    [ForeignKey("ParentId")]
    virtual ParentEntity Parent{get; set;}
    [ForeignKey("YearId")]
    virtual Year Year {get; set;}
}

public class Year{
    [Key]
    int YearId {get; set;}
}

【讨论】:

    【解决方案2】:

    您只需要导航属性上的 ForeignKeyAttribute外键属性。不是都。像这样:

        public class ParentEntity
        {
            [Key, Column(Order = 1)]
            public String Id { get; set; }
            [Key, Column(Order = 2)]
            public int YearId { get; set; }
    
            [ForeignKey("YearId")]
            Year Year;
            public virtual ICollection<ChildEntity> Children { get; set; }
        }
    
        public class ChildEntity
        {
            [Key, Column(Order = 0)]
            public String Id { get; set; }
            [Key, Column(Order = 1)]
            public String ParentId { get; set; }
            [Key, Column(Order = 2)]
            public int YearId { get; set; }
    
            [ForeignKey("ParentId, YearId")]
            public ParentEntity Parent { get; set; }
    
            [ForeignKey("YearId")]
            public Year Year { get; set; }
        }
    
        public class Year
        {
            [Key]
            public int YearId { get; set; }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      • 2014-06-24
      • 2017-04-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多