复杂的 DTO 和 LINQ

本文关键字:LINQ DTO 复杂 | 更新日期: 2023-09-27 18:18:28

class PeopleDTO
{
    string Name { get; set; }
    List<AwardDTO> Awards { get; set; }
}

class AwardDTO
{
    int AwardID {get; set; }
    string AwardName {get; set; }
}

我正在尝试使用 LINQ 筛选我的人员对象,以查找"AwardID"等于 5 的任何人。我已经尝试了以下方法,但我没有得到它:

List<PeopleDTO> people = GetPeople();
var test = (from p in people.Where(a => a.Awards.Where(a => a.AwardID == 5)) select p).ToList();

有什么建议吗?

复杂的 DTO 和 LINQ

people.Where(p=>p.Awards.Any(a=>a.AwardId == 5)).ToList()

你只需要一个小的改变:

List<PeopleDTO> people = GetPeople();
var test = (from p in people.Where(a => a.Awards.Any(a => a.AwardID == 5)) select p).ToList();
var test = people.Where(l => l.Awards.Any(a => a.AwardId == 5));

会做..这只是查询部分,您可能需要执行它。

问题是Where返回匹配的元素序列,因此生成的类型是错误的。这是根本问题:

// Wrong (type error)
from p in people
  .Where(
     // Results in type error as result of Where is Enumerable, not bool.
     // The lambda signature is People => Enumerable[Award] which is
     // incompatible with People => bool required for the outer Where.
     a => a.Awards.Where(a => a.AwardID == 5)
  )
select p
// Working - but NOT ideal as it forces materialization of the
// matching award count! However, types are correct.
from p in people
  .Where(
     // Now we get a lambda: People => bool
     a => a.Awards.Where(a => a.AwardID == 5).Count() > 0
  )
select p

Where(f).Count() > 0更理想的解决方案是Any(f),正如其他答案中所讨论的。除了更清晰之外,Any通常也是有利的,因为它不需要首先具体化序列 - 毕竟,每个源元素都可以匹配。

Where 的实际结果将是IEnumerable[X]IQueryable[X],具体取决于应用它的来源。关键是 Where 本身会导致值不兼容,从而导致错误类型的 lambda。