Lambda:GroupBy多列,其中一列是DbFunctions.TruncateTime()

时间:2018-03-09 20:26:39

标签: asp.net-mvc lambda group-by asp.net-mvc-5

注意:这不是此the API的重复,我的问题是关于TruncateTime子句中的GroupBy。见下面的解释:

我想在多个DbFunctions.TruncateTime子句中使用GroupBy,但它似乎在我的ASP.NET MVC5项目中不起作用。

这是我写的第一个lambda,它给出了一组数据每天的总观看次数 它给了我预期的结果:

var qViews = dbContext.TABLE_C.Where(c => c.IdUser == 1234)
            .Join(dbContext.TABLE_V.Where(v => v.Date > DbFunctions.AddMonths(DateTime.Now, -1)), c => c.Id, v => v.Id, (c, v) => new { c, v })
            .GroupBy(x => DbFunctions.TruncateTime(x.v.MyDateTimeColumn))
            .Select(g => new
            {
                Date = (DateTime)g.Key,
                NbViews = g.Count(),
            }).ToDictionary(p => p.Date, p => p.NbViews);

结果是这样的:

  

...
  日期|查看
  2018年3月7日| 15个
  2018年3月8日| 8
  2018年3月9日| 23



现在,我想要一个更详细的结果,每天的观看次数和每个项目在同一组数据上。

以下是我想写的内容:

var qViews = dbContext.TABLE_C.Where(c => c.IdUser == 1234)
            .Join(dbContext.TABLE_V.Where(v => v.Date > DbFunctions.AddMonths(DateTime.Now, -1)), c => c.Id, v => v.Id, (c, v) => new { c, v })
            .GroupBy(x => new { DbFunctions.TruncateTime(x.v.MyDateTimeColumn), x.c.Id})  // Issue #1
            .Select(g => new
            {
                Date = g.Key.Date,  //Issue #2
                NbViews = g.Count(),
            }).ToDictionary(p => p.Date, p => p.NbViews);

期待类似的东西:

  

...
  日期|意见| ID项目
  2018年3月7日| 4 | 456789个
  2018年3月7日| 11 | 845674个
  2018年3月8日| 6 | 325987个
  2018年3月8日| 1 | 548965个
  2018年3月8日| 1 | 222695个
  2018年3月9日| 23 | 157896

因此,此请求有两个问题(请参阅上面的评论)

问题#1 :我似乎无法GroupBy多个列,其中一个列使用DbFunctions。如果我使用.GroupBy(x => new { x.v.MyDateTimeColumn, x.c.Id }),代码编译,但不会给我预期的结果,因为我想按日期分组,而不是日期+时间

问题#2 Date = g.Key.Date,似乎对编译器有误。当我写g.Key时,自动完成功能只会向我显示Id列,但它没有看到截断日期。

为什么我不能GroupBy多个列,其中一列是截断的日期?
有没有解决方法?

1 个答案:

答案 0 :(得分:1)

如果您想稍后使用它们,则需要提供匿名类型的属性名称:

partial

然后你可以投射:

.GroupBy(x => new 
              { Date = DbFunctions.TruncateTime(x.v.MyDateTimeColumn),
                Id = x.c.Id
              }) 

最后你不能这样做:

.Select(g => new
{
    Date = g.Date,  
    NbViews = g.Count(),
})

因为你会收到这个错误:

  

已添加具有相同键的项目。

为什么呢?因为.ToDictionary(p => p.Date, p => p.NbViews); 不是唯一的,因为您只是按DateDate分组,因此Id(s)将被复制。它与此相同,但这是Date

的列表
string

但是,也许你可能想要这样做:

var nums = new List<string> { "1", "1", "1", "2" };
nums.ToDictionary(x => x, x => x);

现在你可以查看它们了:

var lu = nums.ToLookup(x => x, x => x);