Asp.net mvc Lambda:GroupBy多列,其中一列是DbFunctions.TruncateTime()
注意:这不是重复的,我的问题是Asp.net mvc Lambda:GroupBy多列,其中一列是DbFunctions.TruncateTime(),asp.net-mvc,lambda,group-by,asp.net-mvc-5,Asp.net Mvc,Lambda,Group By,Asp.net Mvc 5,注意:这不是重复的,我的问题是GroupBy子句中的TruncateTime。见以下说明: 我想在multipleGroupBy子句中使用DbFunctions.TruncateTime,但它在我的ASP.NET MVC5项目中似乎不起作用 这是我写的第一个lambda,它给出了一组数据每天的总浏览量。 它给了我预期的结果: var qViews = dbContext.TABLE_C.Where(c => c.IdUser == 1234) .Join(dbCon
GroupBy
子句中的TruncateTime
。见以下说明:
我想在multipleGroupBy
子句中使用DbFunctions.TruncateTime
,但它在我的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年7月3日| 15
2018年8月3日| 8
2018年9月3日| 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年7月3日| 4 | 456789
2018年7月3日| 11 | 845674
2018年8月3日| 6 | 325987
2018年8月3日| 1 | 548965
2018年8月3日| 1 | 222695
2018年9月3日| 23 | 157896 因此,这个请求有两个问题(见上面的评论) 问题#1:我似乎无法
GroupBy
多列,其中哪一列使用DbFunctions
。如果我使用.GroupBy(x=>new{x.v.MyDateTimeColumn,x.c.Id})
,代码会编译,但不会给出预期的结果,因为我希望按日期分组,而不是按日期+时间分组
问题2:Date=g.Key.Date,
对于编译器来说似乎是错误的。当我写g.Key
时,自动完成功能只会提示我Id
列,但它看不到被截断的日期
为什么我不能GroupBy
多列,其中一列是被截断的日期?有什么解决方法吗?如果以后要使用匿名类型的属性,则需要为其指定名称:
.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);
因为您将得到以下错误:
已添加具有相同密钥的项
为什么??因为日期
不是唯一的,因为您只是按日期
和Id
分组,所以日期
(s)将被复制。与此相同,但这是字符串的列表:
var nums = new List<string> { "1", "1", "1", "2" };
nums.ToDictionary(x => x, x => x);
现在您可以查找它们:
// Returns 3 items since there are 3 "1"s
IEnumerable<string> ones = lu["1"];
//返回3项,因为有3个“1”
IEnumerable one=lu[“1”];
x.v.Date不是只返回没有时间的日期吗?至少根据MSDN DateTime.Date返回DateTime对象的日期组件。我只是好奇,这就是我问的原因。这是我的一个坏名字,Date是我的SQL列的名称,它是一个DateTime
(我将其重命名为MyDateTimeColumn
)不用担心,这澄清了我的问题。如果在GroupBy中执行x.v.MyDateTimeColumn.Date,会发生什么请尝试:new{Date=DbFunctions.TruncateTime(x.v.MyDateTimeColumn),Id=x.c.Id}
并在投影过程中使用它。谢谢你的解释,但我仍然不清楚……我一直收到这个错误。是因为MyDateTimeColumn
的名称实际上是Date
,所以在投影过程中有重复吗?@AlexB不,你得到它是因为你是根据两件事进行分组的:Date
和Id
。因此,您将有重复的日期:在问题第1期之前查看您的表格。如果日期
是重复的,您如何将它们设置为字典中的键
?好的,我想我现在明白了!那么基本上,我该如何解决这个问题?我并不真正关心字典
类型,这是我的数据访问层的一种方法。有没有键入更合适?@AlexB你读了我的答案吗?你读了关于查找的最后一部分了吗?你只需要这个:.ToLookup(p=>p.Date,p=>p.NbViews);
而不是ToDictionary(p=>p.Date,p=>p.NbViews)
oops我没有刷新页面,我的不好。查找有效,非常感谢!我以前从未使用过它,我会阅读它。非常感谢:-)
// Returns 3 items since there are 3 "1"s
IEnumerable<string> ones = lu["1"];