Помогите с linq to sql скомпилированный запрос
Я пытаюсь использовать скомпилированный запрос для одного из моих запросов linq to sql. Этот запрос содержит от 5 до 6 объединений. Мне удалось создать скомпилированный запрос, но проблема, с которой я сталкиваюсь, заключается в том, что мой запрос должен проверить, находится ли ключ в коллекции ключей, переданных в качестве входных данных. Но скомпилированные запросы не позволяют передавать коллекцию (поскольку коллекция может иметь различное количество элементов, следовательно, не допускается).
Например
вход в функцию представляет собой набор ключей. Сказать: List<Guid> InputKeys
List<SomeClass> output = null;
var compiledQuery = CompiledQuery.Compile<DataContext, List<Guid>, IQueryable<SomeClass>>(
(context, inputKeys) => from a in context.GetTable<A>()
where inputKeys.Contains(a.Key)
select a);
using(var dataContext = new DataContext())
{
output = compiledQuery(dataContext, InputKeys).ToList();
}
return output;
Приведенный выше запрос не компилируется, поскольку он принимает список в качестве одного из входных данных. Есть ли работа вокруг или лучший способ сделать выше?
1 ответ
Я не уверен, что это возможно, используя только Linq to SQL. Я думаю, что вам нужно иметь хранимую процедуру или функцию, написанную на сервере, которая позволяет передавать строку с разделителями, представляющую ваш список, и анализировать эту таблицу, возвращая таблицу, с которой вы затем можете сравнить.
Я думаю, что самый простой способ сделать это - написать (или сделать так, чтобы ваш администратор БД написал) всю вещь как хранимую процедуру, которая все равно должна будет принимать ваш список в качестве строки для своего аргумента, вызывая вышеупомянутую функцию сплиттера. Хранимая процедура будет иметь свой план выполнения, предварительно скомпилированный сервером.
Вы можете легко превратить ваш список в строку, используя Linq с чем-то вроде
string[] strings = new string[4] { "1", "2", "3", "4" };
string listOfStrings = strings.Aggregate((acc, s) => acc = acc + ", " + s);
Вы можете превратить список всего, что можно привести в строку, в IEnumerable из строк с помощью
IEnumerable<string> strings = list.Cast<string>();
Затем вы можете добавить свою хранимую процедуру в файл dbml и вызвать ее с помощью Linq to SQL.
Кажется, я вспоминаю, что Linq to SQL, чтобы оставаться общим, не обрабатывает списки вещей и преобразует все передаваемые вами списки в параметр для каждой записи в списке.