【问题标题】:Many-to-junction entity in EF6EF6 中的多结实体
【发布时间】:2016-10-01 01:46:06
【问题描述】:

这里有点有趣,我以前没有遇到过。我们在 EF6 中使用注释手动创建了多对多关系:

public class User
{
    public int Id { get; set; }
}

public class School
{
    public int Id { get; set; }
}

public class UserSchool
{
    [Key]
    [Column(Order = 1)]
    public int UserId { get; set; }

    [Key]
    [Column(Order = 2)]
    public int SchoolId { get; set; }

    [Required]
    public virtual User User { get; set; }

    [Required]
    public virtual School School { get; set; }
}

(为简洁起见省略了其他附加属性 - 足以说明我们在联结表上有附加属性,因此我们显式创建它)

所以这很好用——我们可以使用 fluent API 来映射复杂的键,它无关紧要。本质上,我们通过连接将两个标准表连接成多对多。赢家。

现在,我们需要将 junction 表 (UserSchool) 连接到另一个表,同样是多对多:

public class IPAddress
{
    public int Id { get; set; }

    public string IPAddress { get; set; }
}

public class UserSchoolIPAddress
{
    ?? what to put in here

    public virtual UserSchool UserSchool { get; set; }

    public virtual IPAddress IPAddress { get; set; }
}

我已经尝试过通过命名约定和注释指定 ID 属性的流畅 API 映射:流畅 API 映射失败,因为我认为它不喜欢使用导航实体特性;带有注释的 ID 绑定只是在表架构上第二次复制了 UserSchool 属性,从而导致我们出现同步问题。

那么,有没有人遇到过这种情况并找到了解决方案?

【问题讨论】:

    标签: entity-framework entity-framework-6


    【解决方案1】:

    好吧,事实证明我是个白痴。看起来框架实际上会处理我的场景,但是我错误地配置了属性类型,所以出现了不匹配,因此 EF 尝试复制新属性。

    因此,多结点表的完整定义如下:

    public class UserSchoolIPAddress
    {
        [Key]
        [Column(Order = 1)]
        public int UserSchoolUserId { get; set; }
    
        [Key]
        [Column(Order = 2)]
        public int UserSchoolSchoolId { get; set; }   //<-- I had this set to a string for some reason, which broke everything
    
        [Key]
        [Column(Order = 3)]
        public int IPAddress IPAddressId { get; set; }
    
        public virtual UserSchool UserSchool { get; set; }
    
        public virtual IPAddress IPAddress { get; set; }
    }
    

    因此,这将正确地创建第二个连接表,使用 FK 到“多”端(在本例中为 IPAddress)和两个 FK 到“连接”端(UserSchool),并将所有三个 FK 组合在一起在这个“超级路口”上进行一场复杂的PK。干得好 EF!

    【讨论】:

      【解决方案2】:

      您也不需要联结表,如果您以正确的方式配置实体,EF 会为您创建它。

      在您的情况下,您有一个可以拥有许多学校的用户和一个可以拥有许多用户的学校。如果您创建此模型(并通过 fluent api 对其进行配置),EF 将为您创建表 UserSchool,您无需管理它(EF 将为您处理)。

      关于 IPAddress 如果我了解您的模型,IPAddress 由单个学校中的单个用户使用。您的模型,带有一些导航属性可能是这样的。

      public class User
      {
          public int Id { get; set; }
          public virtual ICollection<School> Schools {get; set;}
          public virtual ICollection<IpAddress> IpAddresses {get; set;}
      }
      
      public class School
      {
          public int Id { get; set; }
          public virtual ICollection<User> Users {get; set;}
          public virtual ICollection<IpAddress> IpAddresses {get; set;}
      }
      
      public class IpAddress
      {
          public string Id { get; set; }
          public virtual User User {get; set;}
          public virtual School School {get; set;}
      }
      

      【讨论】:

      • 正如我在原始问题中提到的,我们实际上将附加数据存储为连接映射的属性 - 例如,UserSchool 对象实际上附加了其他外键和权限级别。所以我们需要手动配置它们。
      猜你喜欢
      • 1970-01-01
      • 2021-12-06
      • 2014-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      相关资源
      最近更新 更多