LINQ 左连接、分组依据和计数
LINQ Left Join, Group By and Count
我正在计算每小时发送了多少条消息。但是我的代码 returns 错误结果
这是我使用的原始 sqlite 查询,它工作正常。
SELECT Hours.hour, ifnull(count(Messages.hour),0) as count Hours LEFT JOIN Messages on Messages.hour = Hours.hour by Hours.hour
但我是 LINQ 的新手,这是我的代码和查询。
int[] Hours = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 };
var sortByHour = from h in Hours
join m in Messages on h equals m.Hour into g
orderby h ascending
select new
{
Hour = h,
Total = g.Count()
};
它returns
[0] { Hour = 0, Total = 33485 }
[1] { Hour = 1, Total = 0 }
[2] { Hour = 2, Total = 0 }
[3] { Hour = 3, Total = 0 }
...
[23] { Hour = 23, Total = 0 }
第一个数据有总行数,其他数据有 0。这是错误的。
结果应该是这样的
[0] { Hour = 0, Total = 501 }
[1] { Hour = 1, Total = 408 }
[2] { Hour = 2, Total = 181 }
[3] { Hour = 3, Total = 84 }
...
[23] { Hour = 23, Total = 1055 }
如何修复我的代码?提前致谢。
像这样应该可以解决您的问题。
设置:
int[] Hours = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
var Messages = new List<Message>()
{
new Message() { MessageId = 1, Hour = 5 },
new Message() { MessageId = 2, Hour = 7 },
new Message() { MessageId = 3, Hour = 5 },
new Message() { MessageId = 4, Hour = 3 },
new Message() { MessageId = 5, Hour = 7 },
new Message() { MessageId = 6, Hour = 5 },
};
查询:
var sortByHour = Hours.Select(h =>
new { Hour = h, Total = Messages.Count(m => m.Hour == h) } );
基本上,您每小时只需 select,其计数在 Messages
。
答案是
var res = from h in Hours
join m in Messages on h equals m.Hour into jn
from j in jn.DefaultIfEmpty()
select new
{
hour = h,
count = j != null ? jn.Count(i => i.Hour == h) : 0
}
但是如果你有数据库、模型、时间和消息之间的关系,并且我们正在谈论 linq to sql 或 lint to entities,最好使用(如评论中提到的 usr)h.Messages.Count() 并让数据库引擎发出请求
我正在计算每小时发送了多少条消息。但是我的代码 returns 错误结果
这是我使用的原始 sqlite 查询,它工作正常。
SELECT Hours.hour, ifnull(count(Messages.hour),0) as count Hours LEFT JOIN Messages on Messages.hour = Hours.hour by Hours.hour
但我是 LINQ 的新手,这是我的代码和查询。
int[] Hours = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 };
var sortByHour = from h in Hours
join m in Messages on h equals m.Hour into g
orderby h ascending
select new
{
Hour = h,
Total = g.Count()
};
它returns
[0] { Hour = 0, Total = 33485 }
[1] { Hour = 1, Total = 0 }
[2] { Hour = 2, Total = 0 }
[3] { Hour = 3, Total = 0 }
...
[23] { Hour = 23, Total = 0 }
第一个数据有总行数,其他数据有 0。这是错误的。
结果应该是这样的
[0] { Hour = 0, Total = 501 }
[1] { Hour = 1, Total = 408 }
[2] { Hour = 2, Total = 181 }
[3] { Hour = 3, Total = 84 }
...
[23] { Hour = 23, Total = 1055 }
如何修复我的代码?提前致谢。
像这样应该可以解决您的问题。
设置:
int[] Hours = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
var Messages = new List<Message>()
{
new Message() { MessageId = 1, Hour = 5 },
new Message() { MessageId = 2, Hour = 7 },
new Message() { MessageId = 3, Hour = 5 },
new Message() { MessageId = 4, Hour = 3 },
new Message() { MessageId = 5, Hour = 7 },
new Message() { MessageId = 6, Hour = 5 },
};
查询:
var sortByHour = Hours.Select(h =>
new { Hour = h, Total = Messages.Count(m => m.Hour == h) } );
基本上,您每小时只需 select,其计数在 Messages
。
答案是
var res = from h in Hours
join m in Messages on h equals m.Hour into jn
from j in jn.DefaultIfEmpty()
select new
{
hour = h,
count = j != null ? jn.Count(i => i.Hour == h) : 0
}
但是如果你有数据库、模型、时间和消息之间的关系,并且我们正在谈论 linq to sql 或 lint to entities,最好使用(如评论中提到的 usr)h.Messages.Count() 并让数据库引擎发出请求