IQueryable для IQueryable <T> - PullRequest
       23

IQueryable для IQueryable <T>

4 голосов
/ 11 мая 2011

возможно ли преобразовать объект IQueryable в IQueryable, где T является сопоставленной сущностью? (T будет классом POCO).

Заранее спасибо.

1 Ответ

10 голосов
/ 11 мая 2011

Просто Cast<T>() это.Предполагая, что это запрос того же типа.В противном случае вы можете использовать метод фильтрации OfType<T>() для фильтрации элементов определенного типа.

IQueryable query = ...;
IQueryable<MyType> x = query.Cast<MyType>();  // assuming the queryable is of `MyType` objects
IQueryable<MyDerivedType> y = query.OfType<MyDerivedType>(); // filter out objects derived from `MyType` (`MyDerivedType`)

Однако в вашем случае вы говорите, что используете Dynamic LINQи делать динамическую проекцию.Рассмотрим этот полностью составленный запрос:

var query = dc.SomeTable
              .Where("SomeProperty = \"foo\"")
              .Select("new (SomeProperty, AnotherProperty)");

В результате получается запрос типа IQueryable.Вы не можете привести это к запросу определенного типа IQueryable<T>, в конце концов, что такое T?Библиотека Dynamic LINQ создает тип, производный от DynamicCass.Вы можете привести к IQueryable<DynamicClass> (query.Cast<DynamicClass>()), но у вас не будет доступа к свойствам, поэтому это спорный вопрос.

Действительно, единственная хорошая опция, которую вы имеете, - это использовать dynamic для доступа к этим свойствам в этомcase.

foreach (dynamic x in query)
{
    string someProperty = x.SomeProperty;
    int anotherProperty = x.AnotherProperty;
    // etc...
}

Если вы хотите преобразовать это в запрос ваших объектов POCO, вам придется выполнить преобразование как отдельный шаг, но с использованием LINQ to Objects.

IEnumerable<SomePoco> query =
    dc.SomeTable
      .Where("SomeProperty = \"foo\"")
      .Select("new (SomeProperty, AnotherProperty)")
      .Cast<DynamicObject>().AsEnumerable().Cast<dynamic>()
      .Select(x => new SomePoco
      {
          SomeProperty = x.SomeProperty,
          AnotherProperty = x.AnotherProperty,
      });

Если у вас должен быть IQueryable<T>, то вам не следует использовать динамические проекции в первую очередь.

IQueryable<SomePoco> query =
    dc.SomeTable
      .Where("SomeProperty = \"foo\"")
      .Select(x => new SomePoco
      {
          SomeProperty = x.SomeProperty,
          AnotherProperty = x.AnotherProperty,
      });

Если посмотреть, как приведение не работает для LINQ to Entities, то яПредположим, что единственная возможность получить коллекцию строго типов для ваших объектов POCO - это разбить ее на циклы.

var query = dc.SomeTable
              .Where("SomeProperty = \"foo\"")
              .Select("new (SomeProperty, AnotherProperty)");

var result = new List<SomePoco>();
foreach (dynamic x in query)
{
    result.Add(new SomePoco
    {
        SomeProperty = x.SomeProperty,
        AnotherProperty = x.AnotherProperty,
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...