【问题标题】:Group By Multiple Column In LINQ in C#在 C# 中的 LINQ 中按多列分组
【发布时间】:2017-04-06 22:30:00
【问题描述】:

我有一个类如下:

public class ActualClass
{
    public string BookName { get; set; }
    public string IssuerName { get; set; }
    public DateTime DateOfIssue { get; set; }
    public bool Status { get; set; }
}

表中有以下数据:

我想将它们按 IssuerNameDateOfIssue 分组,用于以下 viewModel 类:

public class ViewModel
{
   public string IssuerName { get; set; }
   public DateTime DateOfIssue { get; set; }
   public List<string> Books { get; set; }
}

并且数据会显示如下:(分组成功后,截图数据会替换为之前的表格数据

特别注意: 按照我的预期,我的 ViewModel 有什么问题吗?

在遵循一些 stackoverflow 答案后,我尝试了很多,但没有一个对我有用。任何帮助将不胜感激。

我试过的代码:

var viewmodel = from b in db.BookIssues
                group b by new
                {
                    b.IssuerName,
                    b.DateOfIssue
                }
                into g
                select new ViewModel()
                {
                    Name = g.key.IssuerName,
                    DateOfIssue = g.Key.DateOfIssue,
                    Books = g.ToList() //Actually this line of code is not working
                };

【问题讨论】:

    标签: c# asp.net-mvc entity-framework linq


    【解决方案1】:

    如果您需要从组结果中选择书籍列表,则需要Books = v.Select(c=&gt;c.BookName).ToList() 还请注意,如果您有时间在发行日期时间,您可能需要使用EntityFunctions.TruncateTime 函数仅按日期部分分组。如果您只存储日期,则可以忽略此功能。

    var viewmodel  = db.BookIssues.GroupBy(x=>new {IssuerName =x.IssuerName, DateOfIssue=EntityFunctions.TruncateTime(x.DateOfIssue) })
    .Select(v=>new ViewModel(){IssuerName =v.Key.IssuerName, DateOfIssue = v.Key.DateOfIssue, Books  = v.Select(c=>c.BookName).ToList() })
    .ToList();
    

    【讨论】:

      【解决方案2】:

      Books = g.ToList() //其实这行不行

      可能是因为 Books 属性的类型是 List&lt;string&gt;,而不是 List&lt;ActualClass&gt;

      你能不能试试这个查询,我添加了b.Select(bn =&gt; bn.BookName).ToList()来只提取书名:

      var books = new List<ActualClass>
      {
         new ActualClass { BookName = "A", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" },
         new ActualClass { BookName = "B", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" },
         new ActualClass { BookName = "C", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" },
         new ActualClass { BookName = "D", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "2" },
         new ActualClass { BookName = "E", DateOfIssue = new DateTime(2015, 10, 10, 12, 10, 0), IssuerName = "2" },
         new ActualClass { BookName = "F", DateOfIssue = new DateTime(2015, 10, 10, 12, 10, 0), IssuerName = "2" }
      };
      
      var result = books.GroupBy(x => new { x.IssuerName, x.DateOfIssue })
                      .Select(b => new ViewModel
                      {
                          Books = b.Select(bn => bn.BookName).ToList(),
                          // Accessing to DateOfIssue and IssuerName from Key.
                          DateOfIssue = b.Key.DateOfIssue,
                          IssuerName = b.Key.IssuerName
                      });
      

      我的分组依据:x.IssuerName, x.DateOfIssue。我通过以下方式在GroupBy() 中传递匿名类型:x =&gt; new { x.IssuerName, x.DateOfIssue }

      现在它们处于密钥状态,您可以在 SELECT 语句中从 KEY 访问 IssuerNameDateOfIssue,如下所示:b.Key.IssuerNameb.Key.DateOfIssue

      【讨论】:

      • 哦!我完全按照你的做法做了,但不幸的是我把 (bn => bn.BookName) 打错了 (bn => bn.IssuerName) 我没有注意到!非常感谢..
      猜你喜欢
      • 1970-01-01
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 1970-01-01
      相关资源
      最近更新 更多