【问题标题】:Entity Framework: foreign keys for many-to-many relations实体框架:多对多关系的外键
【发布时间】:2017-03-21 12:11:23
【问题描述】:

我对多对多关系的导航属性有疑问。 正如我在 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 可以。

感谢您的帮助。

【问题讨论】:

标签: c# entity-framework-6


【解决方案1】:

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

【讨论】:

  • 好的,当 EF 因为不是导航属性而无法加载 Class1Ids 时,为什么它与 Class3Id 一起工作?
  • 因为 Class3Id 是基本属性(和 FK),其他 Id 是集合,无法以这种方式加载集合。
  • 感谢您的信息。我认为这也适用于集合。
【解决方案2】:

Class1下面的类应该有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 外键列

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-11
    • 2017-01-28
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多