Преобразовать объект IQueryable <> в список List <T>?
У меня есть IQueryable<>
.
Я хочу преобразовать его в List<>
с выбранными столбцами, такими как new { ID = s.ID, Name = s.Name }
.
отредактированный
Марк, ты абсолютно прав!
но у меня есть доступ только к FindByAll()
(из-за моей архитектуры).
И это дает мне весь объект в IQueryable<>
И у меня есть строгое требование (для создания объекта json для тега select) иметь только тип list<>
с двумя полями.
Ответы
Ответ 1
Затем просто Select
:
var list = source.Select(s=>new { ID = s.ID, Name = s.Name }).ToList();
(edit) Фактически - имена могут быть выведены в этом случае, поэтому вы можете использовать:
var list = source.Select(s=>new { s.ID, s.Name }).ToList();
который экономит несколько электронов...
Ответ 2
Добавьте следующее:
using System.Linq
... и вызовите ToList()
для IQueryable<>
.
Ответ 3
Конструктор класса List может преобразовать IQueryable для вас:
public static List<TResult> ToList<TResult>(this IQueryable source)
{
return new List<TResult>(source);
}
или вы можете просто преобразовать его без метода расширения, конечно:
var list = new List<T>(queryable);
Ответ 4
System.Linq имеет ToList() для IQueryable < > и IEnumerable < > . Тем не менее, это приведет к полному прохождению данных, чтобы помещать их в список. Когда вы это делаете, вы теряете свой отложенный запрос. Неважно, является ли это потребителем данных.
Ответ 5
Вот несколько методов расширения, с которыми я собрал жюри, чтобы конвертировать IQueryables и IEnumerables из одного типа в другой (т.е. DTO). Он в основном используется для преобразования из более крупного типа (т.е. Типа строки в базе данных с ненулевыми полями) на меньшую.
Положительные стороны этого подхода:
- для этого требуется почти никакой код - простой вызов .Transform
<DtoType>
() - это все, что вам нужно
- он работает так же, как .Select(s = > new {...}), то есть при использовании с IQueryable он создает оптимальный код SQL, исключая поля Type1, которые DtoType не имеет.
LinqHelper.cs:
public static IQueryable<TResult> Transform<TResult>(this IQueryable source)
{
var resultType = typeof(TResult);
var resultProperties = resultType.GetProperties().Where(p => p.CanWrite);
ParameterExpression s = Expression.Parameter(source.ElementType, "s");
var memberBindings =
resultProperties.Select(p =>
Expression.Bind(typeof(TResult).GetMember(p.Name)[0], Expression.Property(s, p.Name))).OfType<MemberBinding>();
Expression memberInit = Expression.MemberInit(
Expression.New(typeof(TResult)),
memberBindings
);
var memberInitLambda = Expression.Lambda(memberInit, s);
var typeArgs = new[]
{
source.ElementType,
memberInit.Type
};
var mc = Expression.Call(typeof(Queryable), "Select", typeArgs, source.Expression, memberInitLambda);
var query = source.Provider.CreateQuery<TResult>(mc);
return query;
}
public static IEnumerable<TResult> Transform<TResult>(this IEnumerable source)
{
return source.AsQueryable().Transform<TResult>();
}