Linq, фильтрующий IQueryable <T> (Система. Данные. Linq. DataQuery), возражают Списком <T> (Система. Набор. Универсальный. Список) объект?

Моя строка 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, который возвращается, Константное выражение самоссылки не поддерживается"

Какие-либо рекомендации?

5
задан Klaptrap 19 April 2010 в 08:21
поделиться

2 ответа

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

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

var teamsheets =
    from t in timesheets
    where usernames.Contains(t.User1.username)
    select t;
3
ответ дан 14 December 2019 в 08:46
поделиться

Linq to Sql попытается сгенерировать запрос sql для представления всего выражения. Это означает, что он попытается передать коллекцию пользователей рекламы в качестве параметров в запрос sql. Если пользователей слишком много, запрос достигнет предела параметра (2100), и его невозможно будет выполнить. Если в команде не так много пользователей, вы можете использовать выражение contains, которое будет преобразовано в выражение «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 из-за размера команды, возможно, стоит подумать об этом.

4
ответ дан 14 December 2019 в 08:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: