Кажется мне, что имеет значение, используете ли Вы переменную для временного хранилища IQueryable или нет. Посмотрите упрощенный пример ниже:
Это работает:
List<string> jobNames = new List<string> { "ICT" };
var ictPeops = from p in dataContext.Persons
where ( from j in dataContext.Jobs
where jobNames.Contains(j.Name)
select j.ID).Contains(p.JobID)
select p;
Но когда я использую переменную для временного хранилища подзапрос, я получаю исключение:
List<string> jobNames = new List<string> { "ICT" };
var jobs = from j in dataContext.Jobs
where jobNames.Contains(j.Name)
select j.ID;
var ictPeops = from p in dataContext.Persons
where jobs.Contains(p.JobID)
select p;
"Система. NotSupportedException: Запросы с локальными наборами не поддерживаются"
Я не вижу, какова проблема. Не эта логика, которая, как предполагается, работает в LINQ?
ОБНОВЛЕНИЕ: Вчера я нашел, что обходное решение получило 1 запрос при использовании нескольких переменных:
var jobs = from j in dataContext.Jobs
where jobNames.Contains(j.Name)
select j.ID;
var ictPeops = from p in dataContext.Persons
join j in jobs on p.JobID equals j
select p;
Но тем не менее я смущен. Кто-либо может пролить некоторый свет на то, почему первый запрос не работал при использовании переменной?
LINQ-2-SQL переводит ваш код в T-SQL. Он может легко передать ваш список имен вакансий в качестве параметра. Но в неудачном запросе вы пытаетесь присоединить таблицу SQL (Persons) к объекту C # (jobs); это сложный тип C #, который нельзя перевести в SQL. Вероятно, вам нужно преобразовать задания в простой массив int, прежде чем использовать его во втором запросе. LINQ-2-SQL может справиться с этим.
попробуйте преобразовать задания var
в тип IList
var jobs = (from j in dataContext.Jobs
where jobNames.Contains(j.Name)
select j.ID).ToList();
Позвольте мне объяснить, как работает Linq to SQL. Когда вы пишете запрос в коде, этот код не выполняется, как другой код .net и Linq to Objects. Затем этот код разбивается на дерево выражений и компилируется в SQL. Если вы пишете все как одно выражение, оно полностью преобразуется в SQL. Когда вы разбиваете на два запроса, он будет разбит на два отдельных запроса. И Linq To SQL не может их собрать.
Из любопытства, это работает? (Я не большой любитель LINQ-to-SQL)
var jobNames = from s in new string[] { "ICT" }
select s;
var jobs = from j in dataContext.Jobs
where jobNames.Contains(j.Name)
select j.ID;
var ictPeops = from p in dataContext.Persons
where jobs.Contains(p.JobID)
select p;
РЕДАКТИРОВАТЬ: Хорошо, а как насчет одного большого запроса? :)
var ictPeops =
from p in dataContext.Persons
let jobs =
from j in dataContext.Jobs
let jobNames = from s in new string[]{"ICT"} select s
where jobNames.Contains(j.Name)
select j.ID
where jobs.Contains(p.JobID)
select p;