Преобразовать объект типа IQueryable <> в тип List <T>? - PullRequest
46 голосов
/ 16 апреля 2009

У меня есть объект IQueryable <>.

Я хочу преобразовать его в список <> с выбранными столбцами, такими как new { ID = s.ID, Name = s.Name }.

Отредактировано

Марк, ты абсолютно прав!

но у меня есть доступ только к методу FindByAll () (из-за моей архитектуры).

И это дает мне весь объект в IQueryable <>.

И у меня строгое требование (для создания объекта json для тега select) иметь только тип list <> с двумя полями.

Ответы [ 5 ]

61 голосов
/ 16 апреля 2009

Тогда просто Select:

var list = source.Select(s=>new { ID = s.ID, Name = s.Name }).ToList();

(правка) На самом деле - в этом случае можно вывести имена, поэтому вы можете использовать:

var list = source.Select(s=>new { s.ID, s.Name }).ToList();

, который экономит несколько электронов ...

40 голосов
/ 16 апреля 2009

Добавить следующее:

using System.Linq

... и звоните ToList() на IQueryable<>.

8 голосов
/ 23 мая 2013

Конструктор класса List может преобразовать IQueryable для вас:

public static List<TResult> ToList<TResult>(this IQueryable source)
{
    return new List<TResult>(source);
}

или вы можете просто конвертировать его без метода расширения, конечно:

var list = new List<T>(queryable);
6 голосов
/ 16 апреля 2009

System.Linq имеет ToList () для IQueryable <> и IEnumerable <>. Это приведет к полному прохождению данных и внесению их в список. Вы теряете свой отложенный вызов, когда вы делаете это. Ничего страшного, если это потребитель данных.

2 голосов
/ 09 сентября 2011

Вот пара методов расширения, которые я пристроил присяжными для преобразования 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>();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...