简体   繁体   English

LINQ左加入,分组和计数

[英]LINQ Left Join, Group By and Count

I'm trying to counting how many messages sent per hour. 我正在尝试计算每小时发送多少邮件。 but my code returns wrong result 但是我的代码返回了错误的结果

This is original sqlite query that I used, it works right. 这是我使用的原始sqlite查询,它正常工作。

SELECT Hours.hour, ifnull(count(Messages.hour),0) as count Hours LEFT JOIN Messages on Messages.hour = Hours.hour by Hours.hour

but I'm a new at LINQ and here is my code and query. 但是我是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()
                 };

and it 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 }

first data has number of total rows and others has 0. its wrong. 第一个数据有总行数,其他数据有0。其错误。

result should have to be like this 结果应该是这样的

[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 }

how can I fix my code? 如何修复我的代码? thanks in advanced. 提前致谢。

Answer is 答案是

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
          }

But if you have Database, model, relation between Hours and Messages, and we are talking about linq to sql or lint to entities, it's better use (as usr mentioned at comments) h.Messages.Count() and let Database engine make a request 但是,如果您具有数据库,模型,小时与消息之间的关系,并且我们正在谈论将linq转换为sql或将lint转换为实体,则最好使用h.Messages.Count()(如注释中的usr所述),并让数据库引擎创建一个请求

Something like this should solve your problem. 这样的事情应该可以解决您的问题。

Setup: 设定:

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 },
                };

Query: 查询:

 var sortByHour = Hours.Select(h =>
    new { Hour = h, Total = Messages.Count(m => m.Hour == h) } );

Basically, you just select each hour and its count in Messages . 基本上,您只需在Messages选择每个小时及其小时数即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM