Linq фильтрует объект IQueryable <T>(System.Data.Linq.DataQuery) с помощью объекта List <T>(System.Collection.Generic.List)? - PullRequest
5 голосов
/ 19 апреля 2010

Моя строка IQueryable:

 // find all timesheets for this period - from db so System.Data.Linq.DataQuery
 var timesheets = _timesheetRepository.FindByPeriod(dte1, dte2);

Строка моего списка:

 // get my team from AD - from active directory so System.Collection.Generic.List
 var adUsers = _adUserRepository.GetMyTeam(User.Identity.Name);

Я хочу показывать расписания только для тех пользователей в коллекции расписаний, которые присутствуют в коллекции пользователей.

Если я использую стандартное выражение c #, например:

 var teamsheets = from t in timesheets
                  join user in adUsers on t.User1.username equals user.fullname
                  select t;

Я получаю сообщение об ошибке «IQueryable, который возвращает выражение константы с собственной ссылкой, не поддерживается»

Любые рекомендации?

Ответы [ 2 ]

4 голосов
/ 19 апреля 2010

Linq to Sql попытается сгенерировать sql-запрос для представления всего выражения. Это означает, что он попытается передать коллекцию пользователей объявлений в качестве параметров в запросе sql. Если пользователей слишком много, запрос достигнет предела параметра (2100) и не может быть выполнен. Если в команде не так много пользователей, вы можете использовать выражение содержимого, которое будет преобразовано в выражение «IN» в sql.

Вот что предложил Стивен:

string[] usernames = adUsers.Select(u => u.fullname).ToArray();

var teamsheets =
from t in timesheets
where usernames.Contains(t.User1.username)
select t;

Единственный способ использовать объединение в том виде, в котором вы пытались, - это извлечь все временные таблицы из базы данных в память (используя ToList для временных таблиц var), и тогда соединение произойдет в памяти. Если это работает лучше, чем использование Contains, или вы не можете использовать Contains из-за размеров команды, возможно, стоит подумать.

3 голосов
/ 19 апреля 2010

Конструкция соединения не будет работать, но вы можете использовать подход Contains. Следующий фрагмент кода может помочь.

string[] usernames = adUsers.Select(u => u.fullname).ToArray();

var teamsheets =
    from t in timesheets
    where usernames.Contains(t.User1.username)
    select t;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...