【问题标题】:Why is my result of type List<IEnumerable<T>>为什么我的 List<IEnumerable<T>> 类型的结果
【发布时间】:2011-08-08 17:07:52
【问题描述】:

应生成帐号(字符串)列表的两个查询。然而,第二个查询实际上返回一个List&lt;IEnumerable&lt;string&gt;&gt;,我希望它返回一个List&lt;string&gt;。我做错了什么?

//the type here resolves to List<string>
var acts = (from a in base.context.Accounts
            select a.AccountNumber).ToList();

//the type here resolves to List<IEnumerable<string>>
var uAccounts = (from u in base.context.Users
                 select u.Accounts.Select(s => s.AccountNumber)).ToList();

【问题讨论】:

  • 您的 select 子句中有一个内部 LINQ 查询,该查询返回一个 IEnumerable&lt;string&gt;,因此在您的外部查询中,您将所有的 IEnumerable&lt;string&gt;s 整理到一个 IEnumerable&lt;IEnumerable&lt;string&gt;&gt;,然后再打开它进入列表。
  • 我将如何重写该查询以达到我想要的结果?

标签: c# .net linq entity-framework entity-framework-4


【解决方案1】:

改变

var uAccounts = (from u in base.context.Users
             select u.Accounts.Select(s => s.AccountNumber)).ToList();

var uAccounts = base.context.Users.SelectMany(u => 
                u.Accounts.Select(s => s.AccountNumber)).ToList();

要真正回答您的问题,您的代码的两行之间的区别在于,第一行遍历每个帐户并仅选择帐号。第二条语句选择IEnumerable&lt;string&gt; 的嵌入式Linq 查询。所以你正在转换为这些IEnumerable&lt;string&gt;中的List&lt;T&gt;

这实际上显示了SelectMany extention method 的好处(我实际上不确定如何在查询语句中使用它)。 SelectMany 方法将您通常收到的IEnumerable&lt;T&gt; 展平为T 元素的单个枚举。所以当ToList() 被调用时,它会返回一个List&lt;string&gt; 而不是可枚举的。

【讨论】:

    【解决方案2】:

    您的 select 子句正在返回/嵌套另一个 select 操作,因此您最终会得到嵌套枚举。要展平列表,您需要改用SelectMany

    var acts = base.context.Accousts
      .SelectMany(a => x.AccountNumber)
      .ToList();
    

    【讨论】:

      【解决方案3】:

      u.Accounts.Select(s =&gt; s.AccountNumber) 本身会给你一个IEnumerable&lt;string&gt;

      然后将其包裹在 from u in base.context.Users select u.Accounts.Select(s =&gt; s.AccountNumber) 中会得到一个 IEnumerable&lt;IEnumerable&lt;string&gt;&gt;

      然后调用.ToList() 得到List&lt;IEnumerable&lt;string&gt;&gt;

      【讨论】:

        【解决方案4】:

        虽然您可以使用 SelectMany,但嵌套 from 子句更直接:

        var uAccounts = (from u in base.context.Users
                          from a in u.Accounts
                            select a.AccountNumber).ToList();
        

        当您使用 NHibernate 之类的产品时,您会想知道这个习惯用法,因为它是在生成的 SQL 代码中进行表连接的一种非常简单的方法。

        【讨论】:

          【解决方案5】:

          在第二个查询中,您正在执行第二个选择来创建您的内部列表

          这会返回一个IEnumerable&lt;string&gt;

           u.Accounts.Select(s => s.AccountNumber)
          

          然后您将其包装在另一个创建外部列表的选择中

          【讨论】:

            【解决方案6】:

            u.Accounts.Select(s =&gt; s.AccountNumber)

            是帐号列表

            所以

            (from u in base.context.Users
                 select u.Accounts.Select(s => s.AccountNumber))
            

            是一个帐号列表的 IEnumerable

            添加 .ToList()

            使其成为帐号列表列表

            【讨论】:

              【解决方案7】:

              我想我需要使用u.Accounts.SelectMany(...) 来获得想要的结果。

              【讨论】:

              • 关闭,但外部选择需要SelectMany
              【解决方案8】:

              在第二种情况下,ToList() 仅适用于外部列表,该列表本身由列表组成。

              【讨论】:

                【解决方案9】:

                u.Accounts.Select(s =&gt; s.AccountNumber) 返回IEnumerable&lt;string&gt;

                select u.Accounts.Select(s =&gt; s.AccountNumber) 返回IEnumerable&lt;IEnumerable&lt;string&gt;&gt;

                select u.Accounts.Select(s =&gt; s.AccountNumber)).ToList(); 只是将外部 IEnumerable 变成 IList

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-02-24
                  • 2021-08-25
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-12-02
                  相关资源
                  最近更新 更多