2012-05-12 2 views
1

Я понимаю, что если у вас есть некоторые функции в Linq запроса, который не отображает на запрос SQL, то вы должны вызвать .AsEnumerable() первая:Каков эффект использования AsEnumerable() для пейджинга?

var model = _service.GetQuery 
        .Where(data => data.SomeFlag == true) 
        .Select(data => new { Foo = CalculateFoo(data.Bar); }); 

не может быть выполнена Linq To SQL, но при добавлении AsEnumerable() мы можем сделать .Select() пункт выполнить с помощью LINQ к объектам, а:

var model = _service.GetQuery 
        .Where(data => data.SomeFlag == true) 
        .AsEnumerable() 
        .Select(data => new { Foo = CalculateFoo(data.Bar); }); 

Но что, если набор данных очень велик - что влияет ли AsEnumerable иметь на пейджинг? Если я говорю:.

var page = model.Skip((page > 0 ? page - 1 : 0) * rows).Take(rows); 

Поскольку модель теперь IEnumerable вместо IQueryable, когда мы говорим model.Skip() Take(), это должно сначала загрузить весь набор данных из базы данных, прежде чем он может пропустить и брать? (Это поражение было цели пейджинга)

EDIT: Вопрос был написан в общем - это конкретные детали:

У меня нет контроля над пейджинга. Я создаю модель и передаю ее в грид-компонент (DevExpress в этом случае, но может быть любой сеткой). Это компонент сетки, который выдает команды пейджинга. Любое решение, которое предполагает использование .Skip(). Take() до того, как AsEnumerable() здесь невозможно.

Так что мне нужно, чтобы быть в состоянии передать эту модель к сетке, а также в то же время, чтобы убедиться, что модель использует отложенное выполнение:

var model = _service.GetQuery 
       .Where(data => data.SomeFlag == true) 
       .Select(data => new { 
        data.Id, 
        data.Customer.Code, 
        data.Customer.Name, 
        // etc, select a few other properties 
        Foo = CalculateFoo(data.Bar); 
       }); 

Так что теперь у меня есть камень против трудной проблемы места :

  • Если я прохожу эту модель к сетке, то будет сгенерировано исключение при отображении текущей страницы, так как LINQ к SQL не может выполнить CalculateFoo()
  • Если добавить AsEnumerable(), то сетка может показать текущей страницы, но для загрузки всего набора данных для этого (загрузка многих тысяч строк только для отображения 200 из них)
  • Если я выйду из столбца Foo из модели, мы снова отложим выполнение, но в таблице отсутствует столбец
+1

возможно дубликат [Понимание .AsEnumerable() в LINQ к SQL] (http://stackoverflow.com/questions/3311244/understanding-asenumerable-in-linq-to-sql) –

+0

Я читал этот вопрос. Он не упоминает пейджинг или эффект, который AsEnumerable имеет при пейджинге. –

+0

AsEnumerable имеет поведение. Неважно, что вы делаете с его результатом. Если вы понимаете это поведение, то вы понимаете это поведение в своем сценарии. –

ответ

1

Если вы подкачки, что вам нужно ... страница, и в общей сложности

так

var query= _service.GetQuery 
        .Where(data => data.SomeFlag == true); 

ViewBag.Total = query.Count(); 
var model = query.Skip((page > 0 ? page - 1 : 0) * rows).Take(rows) 
        .AsEnumerable() 
        .Select(data => new { Foo = CalculateFoo(data.Bar); }); 

Поскольку модель теперь IEnumerable вместо IQueryable, когда мы говорим model.Skip(). Take(), это должно сначала загрузить весь набор данных из базы данных, прежде чем он может пропустить и принять? (Это приведет к поражению цели пейджинга)

Это факт: у вас всегда будет только ваш запрос «принято по linq2entites» до «пейджинга».

EDIT

Я не имею контроль над пейджинга. Я создаю модель и передаю ее в грид-компонент (DevExpress в этом случае, но может быть любой сеткой). Это компонент сетки, который выдает команды пейджинга. Любое решение, которое предполагает использование .Skip(). Take() до того, как AsEnumerable() здесь невозможно.

Ну, «обычно» Сетка-системы разрешают (telerik) (или имеют только (MvcContrib) пользовательский пейджинг (что означает, что вы должны предоставить результаты «выбранной страницы» + общее количество, как в моем ответе).

Я сделал поиск (вы можете пойти дальше) на «DevExpress пользовательской подкачки», которые дают мало результатов. не знаю, если они интересны для вас.

примеров ответа

http://www.devexpress.com/Support/Center/p/Q264453.aspx

http://community.devexpress.com/forums/p/98848/338135.aspx

+0

К сожалению, я не контролирую пейджинг. Все, что я могу сделать, это отправить модель. Я обновлю вопрос с подробностями –

+0

Хорошо, посмотрите на редактирование, если это может помочь –

+0

+1 Спасибо за ссылку - не ответили на вопрос, но это действительно привело меня к осознанию того, что в devex не было правильной подкачки linq в любом случае - на самом деле он загружал все строки, а затем взял одну страницу - точное поведение, которое я пытаюсь избежать здесь. Похоже, у них есть что-то, называемое источником данных linq, которое могло бы помочь решить проблему. –

1

Skip/Take Просто позвоните перед тем AsEnumerable():

var model = _service.GetQuery 
        .Where(data => data.SomeFlag == true) 
        .Skip((page > 0 ? page - 1 : 0) * rows).Take(rows) 
        .AsEnumerable() 
        .Select(data => new { Foo = CalculateFoo(data.Bar); }); 
+0

Мне жаль, что это не так просто :) Вопрос обновлен, чтобы объяснить, почему я не могу поставить .Skip(). Take() before .AsEnumerable() –

 Смежные вопросы

  • Нет связанных вопросов^_^