Вернуть частичный запрос linq из метода - как объявить тип возвращаемого значения

У меня есть запрос linq, написанный в синтаксисе метода. Мне нужно создать очень похожий метод с некоторыми изменениями в окончательном выборе.

Можно ли вернуть частичный запрос Linq из метода, чтобы я не дублировал код? У меня проблема заключается в том, чтобы найти «Тип» запроса, которым нужно пометить метод.

Если я использую query.GetType (), он возвращает (урезанная версия):

SubSonic.Linq.Structure.Query`1[<>f__AnonymousType18`6[advert,client]]

Я попытался создать возвращаемый тип:

SubSonic.Linq.Structure.Query<advert, client> query = new SubSonic.Linq.Structure.Query<advert, client>();

Однако я получаю сообщение об ошибке:

Error   20  Using the generic type 'SubSonic.Linq.Structure.Query<T>' requires '1' type arguments   

Итак, я думаю, я спрашиваю, как объявить возвращаемый тип, который является Subsonic Query, содержащим анонимный тип, содержащий несколько объектов? (2 в моем примере)

Прошу прощения за мой простой пример:

eg:

internal ????? GetQueryBody(string param1, string param2){
    /*  buld the linq query here */
}

internal List<Booking> GetSearchResultsOne(string param1, string param2){
  var query = this.GetQueryBody(string param1, string param2);
  var res = query.Select( db => new Booking { /*fields */).ToList();
  return res;
}

internal List<BookingData> GetSearchResultsTwo(string param1, string param2){
  var query = this.GetQueryBody(string param1, string param2);
  var res = query.Select( db => new BookingData { /*fields*/).ToList();
  return res;
}

Спасибо за уделенное время,

Йохимбо


person Yohimbo    schedule 08.08.2011    source источник
comment
Если я правильно понял, может ли это быть IQueryable ‹WhateverTheQueryIsOperatingOn›?   -  person twoflower    schedule 08.08.2011
comment
re using: IQueryable ‹WhateverTheQueryIsOperatingOn›. Думаю, это мой вопрос - WhateverTheQueryIsOperatingOn - это анонимный объект, содержащий 2 объекта. Как бы я это выразил? IQueryable ‹??‹ реклама, клиент ››?   -  person Yohimbo    schedule 08.08.2011


Ответы (2)


Используйте IEnumerable<T>, чтобы вернуть запрос.

Об анонимном типе: если тип анонимен, как другой метод должен знать об этом? Подробнее здесь. Чтобы решить эту проблему, дайте вашему анонимному типу имя, создав класс.

Если вы хотите вернуть только два типа, вы также можете вернуть кортеж: Тогда T равно Tuple<advert,client>. Вы можете создать кортеж с помощью

var t = new Tuple<advert,client>(client, advert);
person Fox32    schedule 08.08.2011
comment
Я попытался использовать IQueryable в качестве возвращаемого типа, однако компилятор сказал: ** Ошибка 26 'System.Linq.IQueryable' не содержит определения для 'Select' и никакого метода расширения 'Select', принимающего первый аргумент типа 'System .Linq.IQueryable 'можно найти ** - person Yohimbo; 08.08.2011
comment
повторное использование: IEnumerable ‹T›. Думаю, это мой вопрос - T - анонимный объект, содержащий 2 объекта. Как бы я это выразил? Нравится IEnumerable ‹??‹ реклама, клиент ››? - person Yohimbo; 08.08.2011
comment
re: О ссылке анонимного типа. Я не могу создать класс, чтобы обернуть его - это то, что поставщик Subsonic Linq возвращает, когда я выполняю query.GetType (): SubSonic.Linq.Structure.Query1[<>f__AnonymousType186 [реклама, клиент]] ... Хотя спасибо за помощь - person Yohimbo; 08.08.2011
comment
Взгляните на решение кортежа, может быть лучше в вашем случае. Вы можете запустить select на результате поставщика Subsonic Linq и заполнить его. - person Fox32; 08.08.2011
comment
Я думаю, что это больше проблема с поставщиком запросов Subsonic. Тип возврата должен быть типа SubSonic.Linq.Structure.Query1[<>f__AnonymousType186 [объявление, клиент]]. Если я верну кортеж, я больше не смогу выполнять остальную часть проекции linq, поскольку это будет кортеж, а не IQueryable (ну, SubSonic.Linq.Structure.Query, который реализует IQueryable). Тем не менее, спасибо за вашу помощь. - person Yohimbo; 08.08.2011

Ответ 1. Вы не можете этого сделать, потому что Booking и BookingData - это разные типы, поэтому деревья выражений разные.

Ответ 2: Предполагая, что вы можете найти общий базовый класс, есть два подхода к вашему вопросу.

  1. «Тип» того, над чем действует запрос Linq, на самом деле Expression<TDelegate>. Вы можете создавать деревья выражений и хранить их, манипулировать ими, а затем использовать их там, где это необходимо.

  2. «Аргументом» вашего последнего Select () на самом деле является Expression<Func<TSource, TResult>>. Вы можете использовать любую функцию в этом месте, если она соответствует этому делегату.

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

person david.pfx    schedule 04.01.2012