【问题标题】:Filtering "include" entities in EF Core在 EF Core 中过滤“包含”实体
【发布时间】:2019-01-26 00:29:25
【问题描述】:

我有以下型号

 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:包含属性 lambda 表达式 'p => {from PersonRole t in p.PersonRoles where ([t].RoleInDuty.typeOfDutyId == __typeOfDuty_typeOfDutyId_0) 选择 [t]}' 无效。该表达式应表示属性访问: 't => t.MyProperty'。要定位在派生类型上声明的导航, 指定目标类型的显式类型 lambda 参数,例如 '(派生 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();
}

【问题讨论】:

  • 您是否尝试在 where 子句中显式键入 lambda? (PersonRole t) => t.RoleInDuty.typeOfDutyId == Id
  • 你解决它的方式真的很糟糕。您正在从数据库中获取所有数据,将它们加载到内存中并执行过滤器,从而破坏查询点。尽管如此,您的查询听起来倒过来可能会更好。为什么不查询 PersonRoles 的 typeofDutyId 然后在该查询中包含 Person,这样您就可以将所有匹配的 PersonRoles 与其人员匹配
  • @Рома Матковский 虽然你已经解决了这个问题,但请看看我的回答。它肯定会帮助你。谢谢。
  • @Neil.Work 我试过了,不行

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


【解决方案1】:

devnull 显示下一个 How to filter "Include" entities in entity framework?,同样的问题,我看了下,找到了答案。解决我的问题可以用下一个:

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

【讨论】:

    【解决方案2】:

    最后,用 ef core 5 在 Include 中过滤。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();
    

    【讨论】:

      猜你喜欢
      • 2017-09-22
      • 2021-10-01
      • 2021-10-28
      • 1970-01-01
      • 2020-10-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      相关资源
      最近更新 更多