Переполнение стека в LINQ to SQL и ключевое слово Contains - PullRequest
5 голосов
/ 07 июня 2009

У меня есть метод Extension, который должен фильтровать объект Queryable (IQueryable) на основе набора идентификаторов ....

Обратите внимание, что IQueryable поступает из моей базы данных через запрос LinqToSql

 public static IQueryable<NewsItemSummary> WithID(this IQueryable<NewsItemSummary> qry, IQueryable<Guid> Ids)
    {
        return from newsItemSummary in qry
               where Ids.Contains(newsItemSummary.ID)
               select newsItemSummary;
    }

Если Ids созданы из массива или списка и переданы в виде списка с запросами, он НЕ РАБОТАЕТ

Например ...

 GetNewsItemSummary().WithID(ids.AsQueryable<Guid>())

Если Ids составлен из запроса LinqToSql, он работает !!

Это известная проблема: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=355026

Моя коллекция идентификаторов не может быть получена из запроса LinqToSql ...

Обратите внимание, если я изменю функцию так, чтобы она потребляла и IList, а не IQueryable ....

 public static IQueryable<NewsItemSummary> WithID(this IQueryable<NewsItemSummary> qry, IList<Guid> Ids)
    {
        return from newsItemSummary in qry
               where Ids.Contains(newsItemSummary.ID)
               select newsItemSummary;
    }

Теперь я получаю следующее исключение:

Method 'Boolean Contains(System.Guid)' has no supported translation to SQL.

Итак ... все, что я хочу сделать, это отфильтровать мою коллекцию новостей на основе списка или массива Guids .... Идеи ???

1 Ответ

11 голосов
/ 07 июня 2009

Это будет переводить.

public static IQueryable<NewsItemSummary> WithID(
    this IQueryable<NewsItemSummary> qry,
    List<Guid> Ids
)
    {
        return from newsItemSummary in qry
               where Ids.Contains(newsItemSummary.ID)
               select newsItemSummary;
    }
)

Перевод метода Contains для локальных коллекций был одной из последних функций, добавленных при разработке linq для sql для .net 3.5, поэтому есть некоторые случаи, когда вы ожидаете, что работа не будет - например, перевод IList<T>.

Кроме того, имейте в виду, что хотя LinqToSql с радостью переведет списки, содержащие огромное количество элементов (я видел, что он выполняет более 50 000 элементов), SQL Server будет принимать только 2100 параметров для одного запроса.

...