EF6中的多对多实体

时间:2016-10-01 01:46:07

标签: entity-framework entity-framework-6

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

DT

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

所以这很好用 - 我们可以使用流畅的API来映射复杂的密钥,这是非常重要的。基本上,我们通过交汇点将两个标准表加入到多对多中。赢家。

现在,我们需要将联结表(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; } } )加入另一个表,也是多对多表:

UserSchool

我已尝试通过命名约定和注释指定ID属性的流畅API映射 AND :流畅的API映射失败,因为我认为它不喜欢使用导航实体'性能;带有注释的ID绑定只会在表模式上第二次复制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; } } 属性,从而导致我们出现同步问题。

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

2 个答案:

答案 0 :(得分:0)

好的,事实证明我是个白痴。看起来框架将实际处理我的场景,但我已经错误地配置了属性类型,因此存在不匹配,因此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到“many”结尾(在本例中为IPAddress)和两个FK到“结”端(UserSchool),并结合在这个“超级结”上,所有三个FK组合成一个复杂的PK。干得好EF!

答案 1 :(得分:0)

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

在您的情况下,您有一个可以拥有许多学校的用户和一个可以拥有许多用户的学校。如果您创建此模型(并通过流畅的apis进行配置),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;}
}