繁体   English   中英

实体框架相同类型的多个集合

[英]Entity Framework Multiple Collections of Same Type

我试图用两个相同类型的集合创建一个类。 但是,当我读取其中一个集合时,会从两个集合中获取数据。 这意味着我的Fluent API配置一定有问题。

在LINQPad中,我可以看到集合“ Alternatives”和“ Answers”已合并为单个“ PageElements”集合。

样例代码

class Program
{
    static void Main(string[] args)
    {
        var alternatives = new List<PageElement>
            {
                new PageElement {Data = "Alternative 1"},
                new PageElement {Data = "Alternative 2"},
                new PageElement {Data = "Alternative 3"},
                new PageElement {Data = "Alternative 4"},
            };

        var answers = new List<PageElement>
            {
                new PageElement { Data = "Answer 1" },
                new PageElement { Data = "Answer 2" },
            };

        var page = new Page
            {
                Alternatives = alternatives,
                Answers = answers
            };


        using (var context = new MyContext())
        {
            context.Pages.Add(page);
            context.SaveChanges();

            var loadedPage = context.Pages.First();

            foreach (var answer in loadedPage.Answers)
            {
                Console.WriteLine("Answer: " + answer.Data);
            }

        }


        Console.ReadLine();
    }
}



public class MyContext : DbContext
{
    public DbSet<Page> Pages { get; set; }

    public MyContext()
    {

    }

    protected override void OnModelCreating(DbModelBuilder mb)
    {

        mb.Entity<PageElement>()
          .HasRequired(p => p.Page)
          .WithMany(p => p.Alternatives)
          .HasForeignKey(p => p.PageId);

        mb.Entity<PageElement>()
          .HasRequired(p => p.Page)
          .WithMany(p => p.Answers)
          .HasForeignKey(p => p.PageId);

    }

}

public class Page
{
    public int Id { get; set; }
    public virtual ICollection<PageElement> Alternatives { get; set; }
    public virtual ICollection<PageElement> Answers { get; set; }
}

public class PageElement
{
    public int Id { get; set; }
    public int PageId { get; set; }
    public virtual Page Page { get; set; }

    public string Data { get; set; }
}

产量

Answer: Alternative 1
Answer: Alternative 2
Answer: Alternative 3
Answer: Alternative 4
Answer: Answer 1
Answer: Answer 2

期望的输出

Answer: Answer 1
Answer: Answer 2

这是因为您的选择和答案都存储在单个表PageElements -即使您分别构造它们,一旦它们击中数据库,它们也会一起保存。 因此,在重新加载时,EF无法将它们分为两组。

一种简单的解决方案是将它们分为两种类型,例如AlternativeElementAnswerElement ,这将因此创建两个表,从而避免了该问题。

编辑

要回答以下问题:即使子类未添加新字段,也可以遵循派生类的模式。 然后使用“ 每个层次表”模式,这样您就只有一个数据库表,该表具有一列来指示每一行属于哪个子类。

public class PageElement
{
    public int Id { get; set; }
    public int PageId { get; set; }
    public virtual Page Page { get; set; }

    public string Data { get; set; }
}

public class PageElementAnswer : PageElement 
{
}

public class PageElementAlternative : PageElement 
{
}

public class Page
{
    public int Id { get; set; }
    public virtual ICollection<PageElementAlternative> Alternatives { get; set; }
    public virtual ICollection<PageElementAnswer> Answers { get; set; }
}

暂无
暂无

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

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