Convert IQueryable<> type object to List type?

前端 未结 5 1758
广开言路
广开言路 2020-12-02 22:02

I have IQueryable<> object.

I want to Convert it into List<> with selected columns like new { ID = s.ID, Name = s.Name }<

相关标签:
5条回答
  • 2020-12-02 22:30

    Then just Select:

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

    (edit) Actually - the names could be inferred in this case, so you could use:

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

    which saves a few electrons...

    0 讨论(0)
  • 2020-12-02 22:48

    The List class's constructor can convert an IQueryable for you:

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

    or you can just convert it without the extension method, of course:

    var list = new List<T>(queryable);
    
    0 讨论(0)
  • 2020-12-02 22:51

    System.Linq has ToList() on IQueryable<> and IEnumerable<>. It will cause a full pass through the data to put it into a list, though. You loose your deferred invoke when you do this. Not a big deal if it is the consumer of the data.

    0 讨论(0)
  • 2020-12-02 22:51

    Here's a couple of extension methods I've jury-rigged together to convert IQueryables and IEnumerables from one type to another (i.e. DTO). It's mainly used to convert from a larger type (i.e. the type of the row in the database that has unneeded fields) to a smaller one.

    The positive sides of this approach are:

    • it requires almost no code to use - a simple call to .Transform<DtoType>() is all you need
    • it works just like .Select(s=>new{...}) i.e. when used with IQueryable it produces the optimal SQL code, excluding Type1 fields that DtoType doesn't have.

    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>();
    }
    
    0 讨论(0)
  • 2020-12-02 22:53

    Add the following:

    using System.Linq
    

    ...and call ToList() on the IQueryable<>.

    0 讨论(0)
提交回复
热议问题