实体框架中逆属性和外键的区别是什么?

本文关键字:区别 是什么 框架 属性 实体 | 更新日期: 2023-09-27 18:17:04

我知道逆属性是使用当你有多个类之间的关系。但是我在逆属性和外键属性之间感到困惑,因为它们都用于定义关系。

public class PrivilegeToDbOperationTypeMap : BaseEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity), Column(Order = 0)]
    public int PrivilegeToDbOperationTypeMapId { get; set; }
    [ForeignKey("privilegeLookup"), Column(Order = 1)]
    [Index("IX_PrivilegeLookupId_DbOperationLookupId", 1, IsUnique = true)]
    public int PrivilegeLookupId { get; set; }
    [ForeignKey("dbOperationTypeLookup"), Column(Order = 2)]
    [Index("IX_PrivilegeLookupId_DbOperationLookupId", 2, IsUnique = true)]
    public int DbOperationLookupId { get; set; }
    #region Navigation Properties
    public PrivilegeLookup privilegeLookup { get; set; }
    public DbOperationTypeLookup dbOperationTypeLookup { get; set; }
    [InverseProperty("privilegeToDbOperationTypeMap")]
    public ICollection<RoleToPrivilegeDbOperationTypeMap> roleToPrivilegeDbOperationTypeMaps { get; set; }
    #endregion Navigation Properties
}

实体框架中逆属性和外键的区别是什么?

外键属性用于:

  1. 指示与给定外键属性相关的导航属性的名称

    // this is foreign key property with related "privilegeLookup" navigation property. Database column name will be PrivilegeLookupId
    [ForeignKey("privilegeLookup"), Column(Order = 1)]       
    public int PrivilegeLookupId { get; set; }
    // this is related navigation property
    public PrivilegeLookup privilegeLookup { get; set; }
    
  2. OR指示给定导航属性的外键属性名称:

    // this is foreign key property
    public int PrivilegeLookupId { get; set; }
    // this is navigation property with related foreign key property
    [ForeignKey("PrivilegeLookupId")]  
    public PrivilegeLookup privilegeLookup { get; set; }
    

当默认的EF代码优先约定不适用,或者以不适合您的方式应用时,它是有用的。这里你可以看到EF代码优先约定的列表。

当需要指出类A中的导航属性与类B中的另一个导航属性与相同的外键相关时,使用

逆属性。例如:

public class Student
{
    public int StudentID { get; set; }
    public Standard CurrentStandard { get; set; }
    public Standard PreviousStandard { get; set; }
}
public class Standard
{    
    public int StandardId { get; set; }
    public ICollection<Student> CurrentStudents { get; set; }
    public ICollection<Student> PreviousStudents { get; set; }   
}

这里我们有两个类,每个类有两个导航属性。我们的目的是在Student表中有两个外键,可能命名为CurrentStandardId和PreviousStandardId,并且类Standard的导航属性也与相同的外键相关(一对多关系)。然而,在这种情况下,如果没有进一步的指导,EF将无法实现这一点——相反,它将创建4外键。为了引导它,我们必须使用逆属性属性:

public class Standard
{
    public int StandardId { get; set; }
    // reference to the name of another navigation property in class Student
    [InverseProperty("CurrentStandard")]
    public ICollection<Student> CurrentStudents { get; set; }
    // reference to the name of another navigation property in class Student
    [InverseProperty("PreviousStandard")]
    public ICollection<Student> PreviousStudents { get; set; }   
}

现在EF理解了我们的意图,将只创建两个外键,尽管名字可能不太好。要更改列名,还可以使用外键属性:

public class Student 
{
    public int StudentID { get; set; }
    public int CurrentStandardId { get; set; }
    public int PreviousStandardId { get; set; }
    [ForeignKey("CurrentStandardId")]
    public Standard CurrentStandard { get; set; }
    [ForeignKey("PreviousStandardId")]
    public Standard PreviousStandard { get; set; }
}

长话短说- EF可以根据代码约定推断出许多东西。然而,当它不能(例如,当你有两个外键在同一个类)-你必须帮助它使用属性从你的问题。