【问题标题】:Convert IQueryable<> type object to List<T> type?将 IQueryable<> 类型对象转换为 List<T> 类型?
【发布时间】:2010-10-19 20:12:00
【问题描述】:

我有IQueryable&lt;&gt; 对象。

我想将其转换为 List&lt;&gt; 并带有 new { ID = s.ID, Name = s.Name } 等选定列。

编辑

马克,你是绝对正确的!

但我只能访问FindByAll() 方法(因为我的架构)。

它给了我IQueryable&lt;&gt;中的整个对象

而且我有严格的要求(为选择标签创建 json 对象)只有 list&lt;&gt; 类型和两个字段。

【问题讨论】:

  • 那么如果你使用 FindByAll(...).Select(s=>new {ID = s.ID, Name = s.Name}).ToList() 会失败吗?
  • 还要注意我的回答下关于如果需要创建自己的类型的评论。 Json.NET 可能需要可编辑的属性,在这种情况下,您需要自己的类型(C# 匿名类型是不可变的)。

标签: c# list iqueryable


【解决方案1】:

那么就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();

节省了一些电子......

【讨论】:

  • 根据我的层,我只能通过 linq 查询获取整个对象。这就是问题
  • 你能解释一下吗?我不明白评论。
  • 如果你的意思是你需要在层之间返回这个对象,那么你需要创建一个带有 ID 和名称的常规类型,然后 Select(s=>new YourType {ID = s.ID , 名称 = s.Name }).ToList();
  • @Brij 什么问题?非常不清楚;看起来您代码中的主要问题是ToList() 将返回List&lt;T&gt;,而不是ArrayList - 我怀疑简单地使用var data = .... 应该是您的第一步。
【解决方案2】:

添加以下内容:

using System.Linq

...并在IQueryable&lt;&gt; 上致电ToList()

【讨论】:

  • @pauliephonic 你应该开始使用(双关语)ReSharper,然后你就不必再输入另一个 using 语句了 ;-)
  • 简单、精确、美观!
【解决方案3】:

List 类的构造函数可以为你转换一个 IQueryable:

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

当然也可以不用扩展方法直接转换:

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

【讨论】:

  • 欢迎您。我真的很想知道为什么这个扩展最初没有包含在 .NET 中......
  • 对不起,我没有得到你。 “为什么不包含此扩展程序......”是什么意思?但它正在工作。
  • 我的意思是 IQueryable.ToList() 应该已经存在了,我们需要自己添加它作为扩展是很愚蠢的。
【解决方案4】:

System.Linq 在 IQueryable 和 IEnumerable 上有 ToList()。但是,它将导致数据完全通过以将其放入列表中。当你这样做时,你会失去你的延迟调用。如果它是数据的消费者,这没什么大不了的。

【讨论】:

    【解决方案5】:

    这里有几个扩展方法,我已经组合在一起将 IQueryables 和 IEnumerables 从一种类型转换为另一种类型(即 DTO)。主要用于将较大的类型(即数据库中包含不需要字段的行的类型)转换为较小的类型。

    这种方法的积极方面是:

    • 它几乎不需要使用任何代码 - 只需调用 .Transform&lt;DtoType&gt;() 即可
    • 它的工作原理与 .Select(s=>new{...}) 类似,即与 IQueryable 一起使用时,它会生成最佳 SQL 代码,不包括 DtoType 没有的 Type1 字段。

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

    【讨论】:

    • 对于从 Hibernate/NHibernate 世界来到 Linq 的人:功能与 NHibernate 的 .SetResultTransformer(Transformers.AliasToBean(typeof(DtoType))) 或 Hibernate 的 大致相同b>.setResultTransformer(Transformers.aliasToBean(DtoType.class))
    猜你喜欢
    • 2012-11-15
    • 2017-03-11
    • 2011-05-06
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    相关资源
    最近更新 更多