Filtering "include" entities in EF Core

I have the following models

 public class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
    public List<PersonRole> PersonRoles { get; set; }

}

public class RoleInDuty
{
    public int roleInDutyId { get; set; }
    public string Name { get; set; }
    public int typeOfDutyId { get; set; }
    public TypeOfDuty typeOfDuty { get; set; }
    public List<PersonRole> PersonRoles { get; set; }

}
public class PersonRole
{
    public int PersonId { get; set; }
    public Person Person { get; set; }
    public int RoleInDutyId { get; set; }
    public RoleInDuty RoleInDuty { get; set; }
}

And now I can load all people with all their roles using the following code:

 var  people = _context.Persons
      .Include(p => p.PersonRoles)
        .ThenInclude(e => e.RoleInDuty).ToList();

But I wantn't load all data to List, I need load PersonRole according entered typeOfDutyId. I am trying to solve this with the following code

people = _context.Persons
  .Include(p => p.PersonRoles
    .Where(t=>t.RoleInDuty.typeOfDutyId == Id)).ToList();

But VS throw error

InvalidOperationException: The Include property lambda expression 'p => {from PersonRole t in p.PersonRoles where ([t].RoleInDuty.typeOfDutyId == __typeOfDuty_typeOfDutyId_0) select [t]}' is invalid. The expression should represent a property access: 't => t.MyProperty'. To target navigations declared on derived types, specify an explicitly typed lambda parameter of the target type, E.g. '(Derived d) => d.MyProperty'. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393.

As I understand I can't access property RoleInDuty.typeOfDutyId because i'm not include it yet.

I solved this problem with the following code

people = _context.Persons
  .Include(p => p.PersonRoles)
    .ThenInclude(e=>e.RoleInDuty).ToList();       
foreach (Person p in people)
{
  p.PersonRoles = p.PersonRoles
    .Where(e => e.RoleInDuty.typeOfDutyId == Id)
    .ToList();
}

Upvotes: 6

Views: 12311

Answers (2)

Mofaggol Hoshen
Mofaggol Hoshen

Reputation: 738

Finally, filter in Include with ef core 5. Details in MSDN doc: https://learn.microsoft.com/en-us/ef/core/querying/related-data#filtered-include

Var people = _context.Persons
                     .Include(p => p.PersonRoles
                                    .Where(t=>t.RoleInDuty.typeOfDutyId == Id))
                     .ToList();

var blogs = context.Blogs
                   .Include(e => e.Posts.OrderByDescending(post => post.Title).Take(5)))
                   .ToList();

Upvotes: 3

devnull show the next How to filter "Include" entities in entity framework?, and there the same problem, I read it, and find the answer. Solve my problem can with the next:

var temp = _context.Persons.Select(s => new
  {
    Person = s,
    PersonRoles= s.PersonRoles
      .Where(p => p.RoleInDuty.typeOfDutyId == this.typeOfDuty.typeOfDutyId)
      .ToList()
  }).ToList();

Upvotes: 2

Related Questions