2013-12-17 4 views
3

У меня есть следующие LINQ присоединиться:Ошибка преобразования LINQ анонимного типа в IList <>

var query = _ABC.Table 
      .Join(_DEF.Table, cef => ...etc... }) 
      .Join(_GHI.Table, extf => ...etc...}) 
      .Select(jcefn=> new { XYZ = jcefn....etc...}); 

LINQ хорош и возвращает то, что я ожидал (проверено в LINQ клавиатуре).

Я пытаюсь передать запрос в метод расширения с этой подписью:

public PagedList(IQueryable<T> source, int pageIndex, int pageSize) 
{ ... } 

Так я думал, что это было бы приемлемо:

var FPaged = new PagedList<MyObject>(query.ToList(), pageIndex, pageSize); 

Но что, по-видимому, не делает компилятор счастлив. Он говорит:

Аргумент 1: не удается преобразовать из «System.Collections.Generic.List» до «System.Linq.IQueryable т.д.

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

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

Thank you

+2

Не вызывайте ToList() по вашему запросу. Жалоба заключается в том, что она не может быть передана из IQueryable в List. –

+0

ПРАВО ??? Ну, это то, что я сделал первым, и мне сказали: не могу конвертировать из «System.Linq.IQueryable » в 'System.Linq.IQueryable ' – GPGVM

ответ

2

PagedList требует IQueryable<MyQuery>. Ваш объект запроса имеет тип IQueryable<anonymous-type>. Чтобы получить IQueryable<MyQuery> вам нужно изменить свой выбор на:

var query = _ABC.Table 
      .Join(_DEF.Table, cef => ...etc... }) 
      .Join(_GHI.Table, extf => ...etc...}) 
      .Select(jcefn=> new MyObject(){ XYZ = jcefn....etc...}); 

Вам не нужно .ToList(), чтобы превратить это в IQueryable, она уже есть.

Однако, если вы хотите выполнить и кэш IQueriable перед передачей его в функцию, вы могли бы сделать

var cachedQuery = query.ToList(); 
var FPaged = new PagedList<MyObject>(cachedQuery.AsQueryAble<MyObject>(), pageIndex, pageSize); 

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

Но если вы действительно хотите получить все данные только один раз, а затем перевести их в PagedList, это путь. Затем вы можете повторно использовать cachedQuery в других местах, не вызывая другого поиска базы данных.

+0

OHHHHH ... Не чувствую себя глупым !! Это то, чего мне не хватало. Выберите (jcefn => new ** MyObject() ** {XYZ = jcefn .... и т. Д.}}; Смотрите, я не понимал, что могу изменить его от анонимного до объекта в select. Я, хотя мне пришлось делать преобразования после выбора. Я знаю, наверное, тупое нообе для вас, ребята. СПАСИБО! – GPGVM

6

Избавьтесь от списка ToList(). Вам нужно IQueryable не IList

var FPaged = new PagedList(query, pageIndex, pageSize); 
10

Ну да - query.ToList() возвратит List<T>, который не реализует IQueryable<T>. Действительно, ToList() сделает пейджинг менее полезным, так как все это будет сделано локально после извлечения всей таблицы в память.

Просто избавитесь от звонка ToList(), и все может быть в порядке.

EDIT: Хорошо, если это не из-за анонимного типа, добавление звонка ToList не поможет. Вы либо хотите использовать запрос, который проецирует на IQueryable<MyObject>, или, если вы действительно хотите постраничный запрос для анонимного типа, вы можете добавить метод расширения:

public static class PagingExtensions 
{ 
    public static PagedList<T> Paginate<T>(this IQueryable<T> source, 
              int pageIndex, int pageSize) 
    { 
     return new PagedList<T>(source, pageIndex, pageSize); 
    } 
} 

Затем вы можете использовать:

// TODO: Use a more sensible variable name 
var FPaged = query.Paginate(pageIndex, pageSize); 
+0

RIGHT ?? Ну, это то, что я сделал первым, и он сказал мне: не могу конвертировать из «System.Linq.IQueryable » в 'System.Linq.IQueryable ' – GPGVM

+0

@ user1278561 try 'var FPaged = new PagedList (query.ToList (запрос)), pageIndex, pageSize); 'Вы указываете, что PagedList будет использовать тип MyObject, но это анонимный тип. – Harrison

+0

Это потому, что MyObject не совпадает с анонимным типом. Либо выберите его, либо сначала сделайте его MyObject, а не анонимным. В противном случае это похоже на попытку вставить строку в int. – Magus

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