Проблема более интересна, чем кажется на первый взгляд, главным образом потому, что существует много простых решений, но все они должны выполнить 2 подзапроса на проект, чтобы удовлетворить 2 требования.
Например, поскольку Условие
x.ProjectRoles.Count(y => y.Role == "Admin")
обеспечивает наличие только 1 администратора на проект, дополнительное условие, например
&& x.ProjectRoles.Any(y => y.Role == "Admin" && y.UserId == userId)
или
&& x.ProjectRoles.FirstOrDefault(y => y.Role == "Admin").UserId == userId
или
&& x.ProjectRoles.Where(y => y.Role == "Admin").Select(y => y.UserId).Contains(userId)
будет гарантировать, что единственным администратором является данный пользователь.
Другим способом является использование таких критериев, как этот
x.ProjectRoles.Any(y => y.Role == "Admin" && y.UserId == userId)
&& !x.ProjectRoles.Any(y => y.Role == "Admin" && y.UserId != userId)
Другими словами, проект имеет данного пользователя в качестве администратора и не имеет другие администраторы.
На самом деле условие y.UserId == userId
может быть удалено
x.ProjectRoles.Any(y => y.Role == "Admin")
&& !x.ProjectRoles.Any(y => y.Role == "Admin" && y.UserId != userId)
, т.е. у проекта есть администраторы, а также нет других администраторов, кроме данного пользователя, следовательно, у него есть только 1 администратор и он является данным пользователем.
В любом случае, как уже упоминалось в начале, все они выполняют 2 подзапроса на проект. Теперь, если вам интересно (и это интересная часть для меня), если это будет достигнуто с помощью одного подзапроса, ответ - да, с условием, подобным этому:
x.ProjectRoles.Where(y => y.Role == "Admin")
.Min(y => y.UserId == userId ? (int?)1 : 0) == 1
Вот почему. После предложения Where
у нас есть набор администраторов проекта. Теперь выражение
.Min(y => y.UserId == userId ? 1 : 0)
вернет
null
, когда набор пуст (администраторов нет) - 0, если есть Admin, кроме данный пользователь
- 1, когда данный пользователь является администратором, а других администраторов нет
Как мы видим, только возвращаемое значение 1
удовлетворяет обоим требованиям, следовательно, == 1
достигнет желаемой фильтрации.