Dev X
Dev X

Reputation: 119

What is the correct way to load a collection of a reference of an object in EF Core?

Take the following:

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; }
}

I have a ClassB Object loaded and I want to run some code that does a few things, and then changes bar to true.

After I have done this, if every ClassB in the Class A's ClassBs collection has a true, I want to change ClassA's ChangeMe to true.

So, if I have a single ClassB loaded to an object called bla, I would try the following:

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

However, despite having loads of ClassB objects that should be loaded, the only one that I have according to locals is the current, and it seems to enact the Do Something unexpectedly.

I have tried the following:

_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()

And a few more, but, I seem to get various different exceptions.

Short of simply loading another object and calling .Include() in the normal way, is there anyway of achieving what I am trying to do?

Upvotes: 3

Views: 2184

Answers (2)

Ivan Stoev
Ivan Stoev

Reputation: 205849

You can (1) use Query method (available for both reference and collection navigation properties) and (2) combine it with eager loading methods (Include / ThenInclude), e.g.

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

Upvotes: 7

Hani
Hani

Reputation: 554

First I think you should mark your navigation properties as 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; }
}

and then use a chain of Include and ThenInclude

    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
}

Upvotes: 0

Related Questions