Linq-to-Entities совпадает с ID в списке целых чисел в скомпилированном запросе - PullRequest
0 голосов
/ 17 мая 2011

Я пытаюсь найти способ реализовать скомпилированный запрос Linq-to-Entities в форме:

Func<MyEntities, List<int>, IQueryable<MyClass>> query = System.Data.Objects.CompiledQuery.Compile(
    (MyEntities entities, List<int> IDs) => (
         (from au in entities.Mine where IDs.Any(x => x == au.ID) select au)
    ));

Поскольку только переданные скалярные параметры могут быть переданы в CompiledQuery. Скомпилировать вышеописанное не удается.Я пытаюсь найти какой-нибудь умный способ передать список целых чисел через запятую в виде строки и использовать его в запросе L2E по строкам:

Func<MyEntities, string, IQueryable<MyClass>> query = System.Data.Objects.CompiledQuery.Compile(
    (MyEntities entities, string IDs) => (
         (from au in entities.Mine where IDs.Split(',').Any(x => Convert.ToInt32(x) == au.ID) select au)
    ));

Но это не работает из-заНеподдерживаемая функция Split.

Какие-нибудь умные идеи о том, как это можно реализовать?

Ответы [ 3 ]

0 голосов
/ 17 мая 2011

Я закончил тем, что нашел способ сделать это, но он слишком медленный примерно за 3 секунды.

string ids = "|" + String.Join("|", new List<int> { 4, 5, 6, 7, 8, 9, 10, 20, 23, 34 }) + "|";   

Func<MyEntities, string, IQueryable<MyClass>> query =     System.Data.Objects.CompiledQuery.Compile(
(MyEntities entities, string IDs) => (
     (from au in entities.Mine where IDs.Contains("|" + SqlFunctions.StringConvert((decimal)au.ID).Trim() + "|")select au)
)); 

Вернуться к чертежной доске.

0 голосов
/ 18 мая 2011

Вы не можете.

Что делает CompiledQuery?Он предварительно преобразует запрос в каноническое дерево команд - промежуточное представление, используемое поставщиком для генерации SQL.

SQL для команды со скалярным параметром имеет одинаковую структуру независимо от значения параметра.Но SQL, сгенерированный, скажем, для списка из 2 элементов, будет структурно отличаться от SQL для списка из 3 элементов, поскольку в предложении WHERE требуется один меньший предикат OR.В конце концов, большинство серверов БД не принимают списки в качестве значения параметра.

Ваша строка / | kludge работает, потому что теперь вы передаете только один параметр, а не список, серверу БД.Но, как вы видели, сервер не может индексировать такой запрос, поэтому он будет медленным.

0 голосов
/ 17 мая 2011

Я не уверен, что это может сработать, но, возможно, попробуйте использовать join из List<int> IDs и MyEntities entities?

...