繁体   English   中英

实体框架:用于多对多关系的外键

[英]Entity Framework: foreign keys for many-to-many relations

我对多对多关系的导航属性有疑问。 正如我在MSDN上阅读的那样,有一个选项可以将ForeignKey属性定义为导航属性。 现在,我想将此功能用于多对多关系,但我无法使其正常工作。

我正在使用EF 6.1.3。

我的课程:

public class Class1
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [ForeignKey(nameof(Class2s))]
    public ICollection<Guid> Class2Ids { get; set; }

    [ForeignKey(nameof(Class2Ids))]
    public ICollection<Class2> Class2s { get; set; }

    [ForeignKey(nameof(Class3))]
    public Guid Class3Id { get; set; }

    public Guid Class3 { get; set; }
}

public class Class2
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [ForeignKey(nameof(Class1s))]
    public ICollection<Guid> Class1Ids { get; set; }

    [ForeignKey(nameof(Class1Ids))]
    public ICollection<Class1> Class1s { get; set; }
}

public class Class3
{ 
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; } 
}

导航属性被加载但id集合保持为空的问题。

public static void Main(string[] args)
{
    using (SomeContext context = new SomeContext())
    {
        var classes = context.Classe1Set
            .Include(c => c.Class2s)
            .Include(c => c.Class2s)
            .First();

        classes.Class3;     // filled with correct object
        classes.Class3Id;   // filled with correct guid

        classes.Class2s;    // is filled with 2 elements
        classes.Class2Ids;  // problem: is Empty List
    }
}

我究竟做错了什么?

编辑:更新了类以更好地表示问题。 在数据库端正确创建了多对多连接。 问题只是属性Class1Ids无法正确填充,而Class3Id可以正确填充。

谢谢你的帮助。

您不需要ForeignKey属性-该关系将根据类型推断。
Class1IdsClass2Ids不指向另一个实体,不是导航属性,并且不能由EF自动加载。
要获得所需的内容,您应该像这样定义Ids属性
public ICollection<Guid> ClassXIds { get { return ClassXs.Select(c => c.Id).ToList(); } } public ICollection<Guid> ClassXIds { get { return ClassXs.Select(c => c.Id).ToList(); } } 这不会从数据库加载数据,只是从导航属性中提取ID。

在Class1之下,Class应该具有Class2的集合导航属性,而Class2应该具有Class1的集合导航属性,这将在Class1和Class2之间创建多对多关系,如下所示:

public class Class1
{
    public Class1() 
    {
        this.Courses = new HashSet<Course>();
    }

    public int Class1Id { get; set; }

    public virtual ICollection<Class2> Class2s { get; set; }
}

public class Class2
{
    public Class1()
    {
        this.Class1s = new HashSet<Class1>();
    }

    public int Class2Id { get; set; }

    public virtual ICollection<Class1> Class1s { get; set; }
}

然后,您将在数据库上获得一个名为Class1Class2的表,其中字段Class1_Class1Id作为主键,另一个Class2_Class2Id作为主键

默认情况下,EF将查找与主体实体主键名称相同名称的外键属性。 如果不存在外键属性,则EF将在Db表中使用+“ _” +创建FK列,例如,如果Class1实体不包含Class1的外键属性(其中Class1包含Class1Id),则EF将在Class1表中创建Class1_Class1Id外键列

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM