#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: Я расширил свой ответ. Надеюсь, теперь это будет более понятно.