Моя строка 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, который возвращается, Константное выражение самоссылки не поддерживается"
Какие-либо рекомендации?
Конструкция соединения не будет работать, но вы можете использовать подход Содержит
. Следующий фрагмент может помочь.
string[] usernames = adUsers.Select(u => u.fullname).ToArray();
var teamsheets =
from t in timesheets
where usernames.Contains(t.User1.username)
select t;
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 из-за размера команды, возможно, стоит подумать об этом.