【问题标题】:What is the correct way to load a collection of a reference of an object in EF Core?在 EF Core 中加载对象引用集合的正确方法是什么?
【发布时间】:2019-06-24 01:45:20
【问题描述】:

采取以下措施:

public class ClassA
{
    public int ID { get; set; }
    public ICollection<ClassB> ClassBs { get; set; }
    public bool ChangeMe { get; set; }
}

public class ClassB
{
    public int ID { get; set; }
    public string test { get; set; }
    public bool bar { get; set; }
    public ClassA ClassA { get; set; }
    public int ClassAID { get; set; }
}

我加载了一个 ClassB 对象,我想运行一些代码来做一些事情,然后将 bar 更改为 true。

我做完这个之后,如果Class A的ClassBs集合中的每一个ClassB都有一个true,我想把ClassA的ChangeMe改成true。

因此,如果我将一个 ClassB 加载到名为 bla 的对象中,我会尝试以下操作:

if (bla.ClassA.ClassBs.Where(x => x.bar == false).Count() == 0)
{
    Do Something
}

然而,尽管有大量的 ClassB 对象应该被加载,但根据当地人的说法,我唯一拥有的是当前的,而且它似乎意外地制定了 Do Something

我尝试了以下方法:

_context.Entry(bla).Reference(x => x.ClassA).Load()
_context.Entry(bla).Collection(x => x.ClassA.ClassBs).Load()
_context.Entry(bla.ClassA).Collection(x => x.ClassBs).Load()

还有一些,但是,我似乎遇到了各种不同的例外情况。

没有简单地加载另一个对象并以正常方式调用.Include(),有没有实现我想要做的事情?

【问题讨论】:

  • 您遇到了哪些异常?文档将 Entry().Collection().Load() 指定为显式加载集合导航属性的方式。

标签: c# asp.net entity-framework entity-framework-core


【解决方案1】:

您可以 (1) 使用 Query 方法(可用于引用和集合导航属性)和 (2) 将其与预加载方法(Include / ThenInclude)结合使用,例如

_context.Entry(bla).Reference(x => x.ClassA)
    .Query() // <-- (1)
    .Include(x => x.ClassBs) // <-- (2)
    .Load();

【讨论】:

    【解决方案2】:

    首先我认为您应该将导航属性标记为virtual

     public class ClassA
    {
        public int ID { get; set; }
        public virtual ICollection<ClassB> ClassBs { get; set; }
        public bool ChangeMe { get; set; }
    }
    
    public class ClassB
    {
        public int ID { get; set; }
        public string test { get; set; }
        public bool bar { get; set; }
        public virtual ClassA ClassA { get; set; }
        public int ClassAID { get; set; }
    }
    

    然后使用IncludeThenInclude的链

        var bla = _context.Set<ClassB>().Include(cb=>cb.ClassA).ThenInclude(ca=>ca.ClassBs).ThenInclude(cb=>cb.ClassA).Where(x=>x.Id=blaId)
    if (bla.ClassA.ClassBs.Where(x => x.bar == false).Count() == 0)
    {
       Do Something
    }
    

    【讨论】:

    • 导航属性不需要是虚拟的,如果你还是要使用急切加载...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-15
    相关资源
    最近更新 更多