IQueryable к IQueryable

#linq #entity-framework

#linq #entity-framework

Вопрос:

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

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

Комментарии:

1. И как вы получаете не универсальный IQueryable ?

Ответ №1:

Просто 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`)
  

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

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

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

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

 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,
    });
}
  

Комментарии:

1. Я получаю систему. Исключение: не удается выполнить приведение типа .. Linq к сущностям поддерживал приведение только для примитивного типа..

2. Все, что мне нужно, это получить IQueryable<T>, начиная с dynamics linq для entity: шаг 1: у меня есть что-то вроде этого -> var query1 = myCtx. Где (..lambda); шаг 2: Я должен выбрать только некоторое поле (я не могу использовать lambda здесь), поэтому: var query2 = query1. Выберите(«myFiled1, myFiled2»); шаг 2 достижим с помощью System.Linq от ScottGu. Dynamic.dll библиотека. проблема здесь: шаг 2 возвращает IQueryable, в то время как мне нужно IQueryable<T> , где T — мой класс POCO. Я не в состоянии обратиться.. Я всегда получаю исключение во время преобразования..

3. @Alex: Это информация того рода, которая была бы полезна, когда вы задавали вопрос. Что ж, в этом случае вы не можете привести к определенному типу, поскольку вы проецируете на динамический тип и технически вы не знаете тип во время компиляции. DynamicClass Однако вы можете привести к a, поскольку это тип, от которого происходят эти объекты, хотя вы не сможете получить прямой доступ к полям, если не используете dynamic переменные.

4. Пожалуйста, не могли бы вы привести мне такой же пример? Я не уверен, что понял ваш ответ..

5. @Alex: Я расширил свой ответ. Надеюсь, теперь это будет более понятно.