EF Core中过滤“包含”实体

6
我有以下模型。
 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; }
}

现在,我可以使用以下代码加载所有人员及其角色:

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

但我不想将所有数据加载到List中,我需要根据输入的typeOfDutyId加载PersonRole。

我尝试使用以下代码解决此问题:

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

但是VS报错了

InvalidOperationException: Include属性的lambda表达式'p => {from PersonRole t in p.PersonRoles where ([t].RoleInDuty.typeOfDutyId == __typeOfDuty_typeOfDutyId_0) select [t]}'无效。表达式应该表示属性访问:'t => t.MyProperty'。要针对派生类型声明的导航,请指定目标类型的显式类型化的lambda参数,例如'(Derived d) => d.MyProperty'。有关包含相关数据的更多信息,请参见http://go.microsoft.com/fwlink/?LinkID=746393

据我所知,我不能访问属性RoleInDuty.typeOfDutyId,因为我还没有将其包含进来。

我使用以下代码解决了这个问题

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

1
可能是如何在Entity Framework中过滤“Include”实体?的重复问题。 - devNull
你试过在where子句中显式地为lambda表达式指定类型吗? (PersonRole t) => t.RoleInDuty.typeOfDutyId == Id - Neil.Work
你解决问题的方式真的很糟糕。你从数据库中获取所有数据,将它们加载到内存中并进行过滤,这就违背了查询的目的。不过你的查询听起来可以通过反向思考变得更好。为什么不查询 PersonRoles 以获取 typeofDutyId,然后在查询中包含 Person,这样你就可以获得所有匹配的 PersonRoles 和他们的 personrs。 - npo
@Neil.Work 我试过了,不起作用。 - Рома Матковский
@npo 我尝试这样做,但结果我得到的是一个PersonRoles集合,其中每个PersonRole都有一个Person。但我需要将IEnumerable<Person>返回到我的View。 - Рома Матковский
显示剩余2条评论
2个回答

3

2

Devnull展示了下一个如何在Entity Framework中过滤“Include”实体?,并且有相同的问题,我阅读了它,并找到了答案。解决我的问题可以使用以下方法:

原始答案:最初的回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接