Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering "include" entities in EF Core

Tags:

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();
}
like image 929
Рома Матковский Avatar asked Jan 26 '19 00:01

Рома Матковский


People also ask

How does include work in EF core?

The Include method lets you add related entities to the query result. In EF Classic, the Include method no longer returns an IQueryable but instead an IncludeDbQuery that allows you to chain multiple related objects to the query result by using the AlsoInclude and ThenInclude methods.

How do you load entities or data in EF?

Entity Framework supports three ways to load related data - eager loading, lazy loading and explicit loading. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

What are entities in dotnet?

Entity Framework is an open-source ORM framework for . NET applications supported by Microsoft. It enables developers to work with data using objects of domain specific classes without focusing on the underlying database tables and columns where this data is stored.

What is primary key in EF core?

Configuring a primary key By convention, a property named Id or <type name>Id will be configured as the primary key of an entity. Owned entity types use different rules to define keys. You can configure a single property to be the primary key of an entity as follows: Data Annotations.


1 Answers

Finally, filter in Include with ef core 5. Details in MSDN doc: https://docs.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();
like image 125
Mofaggol Hoshen Avatar answered Oct 04 '22 02:10

Mofaggol Hoshen