IEnumerable против IQueryable - PullRequest
       16

IEnumerable против IQueryable

1 голос
/ 16 января 2011

У меня есть запрос:

topics.OrderBy(x => x.Replies.Any() ? x.Replies.OrderBy(y => y.PostedDate).Last().PostedDate : x.PostedDate);

Он сортирует коллекцию тем по последнему ответу или, если он не имеет ответа, то по своей дате публикации.Он отлично работает и хорошо выполняет свою работу.Тем не менее, это работает только если темы имеют тип IEnumerable<Topic>.Если я пытаюсь сделать его `IQueryable ', я получаю сообщение о том, что метод расширения Last () неизвестен или что-то в этом роде.

Кто-нибудь знает почему?По какой-то причине получение x.Replies.Last() в этом запросе, когда темы IQueryable, выдает это исключение.

Я бы хотел, чтобы темы были IQueryable, поскольку я сначала загружаю темы со всеми темами из базы данных, отсортированными по последнему ответу.Затем я делаю .Skip () и .Take () по темам для подкачки страниц.Однако в настоящее время он вытягивает ВСЕ темы в память, а затем выполняет .Skip () и .Take () для коллекции в памяти.Это неприемлемо, потому что чем больше тем добавлено на форум, тем больше времени требуется для загрузки сайта, особенно когда база данных не работает на том же компьютере, что и сайт.Мне нужна база данных, чтобы вернуть только постраничные строки, а не все строки.Я хочу, чтобы подкачка происходила на уровне базы данных.

Есть идеи?

PS - я использую LINQ для сущностей с Entity Framework 4.0

Ответы [ 4 ]

3 голосов
/ 16 января 2011

Вы пробовали topics.OrderBy(x => x.Replies.Any() ? x.Replies.Max(y => y.PostedDate) : x.PostedDate);?

1 голос
/ 19 апреля 2012

IEnumerable: LINQ to Object и LINQ to XML.

IQueryable: LINQ to SQL

1 голос
/ 16 января 2011

Ваш контекст к базе данных все еще активен, когда вы пытаетесь запустить опубликованный код? Если вы (или .NET) удалили контекст базы данных, вы больше не сможете получить доступ к данным в объекте IQueryable, поскольку соединение потеряно.

/ Viktor

0 голосов
/ 16 января 2011

Я думаю, что EF не может правильно перевести ваш запрос, это происходит.Поскольку нет необходимости, чтобы каждая лямда успешно конвертировалась в esql, у нее есть свои ограничения.Я думаю, что это очень сложный SQL-запрос для того, что вы ищете.

Я предлагаю вам создать новое поле DateTime в ваших темах под названием «LastUpdate», которое будет по умолчанию установлено в PostDate темы, когда оно будетсоздано.Во-вторых, когда вы добавляете новый ответ, вы также обновляете LastUpdate темы.

Делая это, вы также делаете свой запрос очень простым и избегаете ненужного присоединения при создании запроса.Вам не нужно искать таблицу ответов PostDate с любым объединением.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...