2011-02-08 4 views
0

Я пытаюсь использовать скомпилированный запрос для одного из моих запросов linq to sql. Этот запрос содержит от 5 до 6 объединений. Мне удалось создать скомпилированный запрос, но проблема, с которой я столкнулся, - это мой запрос, чтобы проверить, находится ли ключ в коллекции ключей, переданных в качестве входных данных. Но скомпилированные запросы не позволяют передавать коллекцию (поскольку коллекция может иметь различное количество элементов, поэтому не допускается).Help with linq to sql compiled query

Например

вход функции представляет собой набор ключей. Скажи: 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; 

Этот запрос не компилируется, так как он принимает список в качестве одного из входов. Есть ли какая-нибудь работа или лучший способ сделать это?

+0

Можете ли вы просто использовать обычный запрос вместо скомпилированного? – Gabe

+0

@Gabe: Я мог бы. Но, как я уже говорил, это сложный запрос, и я хочу посмотреть, могу ли я каждый раз исключать затраты на его сборку. Благодарю. – stackoverflowuser

ответ

0

Я не уверен, что это возможно, используя только Linq to SQL. Я думаю, вам нужно иметь хранимую процедуру или функцию, написанную на сервере, которая позволяет передавать строку с разделителями, представляющую ваш список, и анализирует, что возвращает таблицу, которую вы можете сравнить с ней.

Я думаю, что самый простой способ сделать это - написать (или записать ваш DBA) всю вещь как хранимую процедуру, которая все равно должна будет взять ваш список как строку для его аргумента, вызвав вышеупомянутый сплиттер функция. Хранимая процедура будет иметь план выполнения, предварительно скомпилированный сервером.

Вы можете легко сделать свой список в строку, используя 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, чтобы оставаться общим, не имеет дело со списками вещей и преобразует все списки, которые вы передаете в параметр для каждой записи в списке.