注意:这不是此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
多个列,其中一列是截断的日期?
有没有解决方法?
答案 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);
不是唯一的,因为您只是按Date
和Date
分组,因此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);