62 votes

Convertir un objet de type IQueryable<> en un objet de type List<T> ?

J'ai IQueryable<> objet.

Je veux le convertir en List<> avec des colonnes sélectionnées comme new { ID = s.ID, Name = s.Name } .

Édité

Marc, tu as tout à fait raison !

mais je n'ai accès qu'à FindByAll() Méthode (en raison de mon architecture).

Et il me donne tout l'objet en IQueryable<>

Et j'ai une exigence stricte (pour créer l'objet json pour la balise select) d'avoir seulement list<> avec deux champs.

81voto

Marc Gravell Points 482669

Ensuite, il suffit de Select :

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

(edit) En fait, les noms peuvent être déduits dans ce cas, vous pouvez donc utiliser :

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

ce qui permet d'économiser quelques électrons...

52voto

Hannoun Yassir Points 6385

Ajouter ce qui suit :

using System.Linq

...et appeler ToList() sur le IQueryable<> .

8voto

mmmeff Points 174

Le constructeur de la classe List peut convertir un IQueryable pour vous :

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

ou vous pouvez simplement le convertir sans la méthode d'extension, bien sûr :

var list = new List<T>(queryable);

6voto

Brian Genisio Points 30777

System.Linq dispose de ToList() sur IQueryable<> et IEnumerable<>. Cependant, il faut passer par toutes les données pour les mettre dans une liste. Vous perdez votre invocation différée lorsque vous faites cela. Ce n'est pas grave s'il s'agit du consommateur des données.

2voto

Vedran Points 2107

Voici quelques méthodes d'extension que j'ai assemblées pour convertir les IQueryables et les IEnumerables d'un type à un autre (c'est-à-dire un DTO). Cette méthode est principalement utilisée pour convertir un type plus grand (c'est-à-dire le type de la ligne dans la base de données qui a des champs inutiles) en un type plus petit.

Les aspects positifs de cette approche sont les suivants :

  • son utilisation ne nécessite pratiquement pas de code - un simple appel à .Transform <DtoType> () est tout ce dont vous avez besoin
  • il fonctionne comme .Select(s=>new{...}), c'est-à-dire que lorsqu'il est utilisé avec IQueryable, il produit le code SQL optimal, à l'exclusion des champs Type1 que DtoType n'a pas.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X