Некоторая часть вашего оператора SQL слишком глубоко вложена С# EF 5

Я получаю следующее исключение из EF 5: Некоторая часть вашего оператора SQL слишком сложна. Перепишите запрос или разделите его на более мелкие запросы.

Вот мой запрос:

String username = "test";
IEnumerable<int32> roles;
IEnumerable<int32> applications;
cnx.Users.Where ( it =>
( userName != null ? it.name = = userName : true ) &&
( !roles.Any () || roles.Contains ( it.role_id ) ) &&
( ! applications.Any () || applications.Contains ( it.application_id ) ) )
 .Count ();
</int32></int32>

Пользователи - это простая таблица. Роли и приложения являются типами IEnumerable и могут быть пустыми.

Как я могу изменить свой запрос, что он будет работать в EF 5 (.Net 4.0)?

2 ответа

Для меня это выглядит так: userName, roles и applications являются параметрами запроса, то есть данные поступают из вашего приложения, а не из базы данных. В этом случае я бы написал запрос следующим образом:

IQueryable<user> query = cnt.Users;
if(userName != null)
 query = query.Where(x => x.name == userName)
if(roles.Any())
 query = query.Where(x => roles.Contains(x.role_id));
if(applications.Any())
 query = query.Where(x => applications.Contains(x.application_id))
var result = query.Count();
</user>

Это намного более читаемо и не включает ненужный беспорядок в результирующий запрос.

Обратите внимание, что roles и applications не должны представлять неисполненный результат другого запроса. С "невыполненным результатом" я имею в виду следующее:

IEnumerable<role> roles = context.Roles.Where(x => x = y);
</role>


Другое решение - перебирать записи, получающие другие, и агрегировать их в конечный список.

Это не самый быстрый, а не красота, но решит.

licensed under cc by-sa 3.0 with attribution.