简体   繁体   English

Linq使用SUM和Group By查询两个表

[英]Linq query for two tables using SUM and Group By

I have two tables 我有两张桌子

Replies 回复

|ReplyID     |ReplyText | QuestionID | CreatedOn  |
|1           |xxxxxx    |1           | 01/01/2016 |
|2           |yyyyyy    |2           | 02/01/2016 |
|3           |zzzzzz    |3           | 03/01/2015 |

and Votes 和投票

|ReplyID     |VoteValue |UserId   |
|1           |1         |1        |
|1           |1         |2        |
|2           |-1        |3        |
|3           |1         |4        |

I m trying to join two tables on ReplyIds against id value which I m getting as a controller parameter. 我试图将RELIds上的两个表连接到id值,我将其作为控制器参数。

This is the linq query I m using: 这是我使用的linq查询:

Replies = from r in db.Replies
          join v in db.Votes on r.ReplyID equals v.ReplyId
          where r.QuestionId == id
          orderby r.CreatedOn descending
          group v by v.ReplyId into g
          select g.Key

where Replies is 回复的地方

public IGrouping<Reply, Vote> Replies { get; set; }

I m having this error: 我有这个错误:

Cannot implicitly convert type 'System.Linq.IQueryable' to System.Linq.IGrouping' 无法将类型'System.Linq.IQueryable'隐式转换为System.Linq.IGrouping'

I m unable to proceed from here. 我无法从这里出发。 I need to Sum(VoteValues) in Votes table and join it with Replies table to get all column values. 我需要在Votes表中使用Sum(VoteValues)并将其与Replies表连接以获取所有列值。 Any help would be appreciated. 任何帮助,将不胜感激。

You can use a group join instead: 您可以改为使用组连接

var result= from r in db.Replies
            join v in db.Votes on r.ReplyID equals v.ReplyId into votes
            where r.QuestionId == id
            orderby r.CreatedOn descending
            select new {Reply=r, Votes=votes.Sum(v=>v.VoteValue)};

According what you describe you need to get all columns from Reply and the sum of all votes. 根据您的描述,您需要从“ Reply ”和所有投票的总和中获取所有列。 This way you can project your query using an anonymous to save the Reply instance and the sum that you need. 这样,您可以使用匿名项目来设置查询,以保存Reply实例和所需的总和。 Now, maybe you need to save the projection in a known type because you need to pass the result of this query to a controller. 现在,您可能需要将投影保存为已知类型,因为您需要将此查询的结果传递给控制器​​。 In that case I suggest create a custom class (also known as DTO): 在这种情况下,我建议创建一个自定义类(也称为DTO):

public class ReplySum
{ 
  public Reply Reply {get;set;}
  public int Votes{get;set;}
}

And now you can project your query this way: 现在,您可以通过以下方式投影查询:

IQueryable<ReplySum> query =from r in db.Replies
                            join v in db.Votes on r.ReplyID equals v.ReplyId into votes
                            where r.QuestionId == id
                            orderby r.CreatedOn descending
                            select new ReplySum{Reply=r, Votes=votes.Sum(v=>v.VoteValue)};

Another thing you need to consider is materialize your query before pass the result to your view: 您需要考虑的另一件事是在将结果传递给视图之前实现查询:

var result=query.ToList();//Or ToArray

Your query can be simpler by using lambda expression: 使用lambda表达式可以更简单地查询:

var result = db.Replies.Select(i => new
                    {
                        VoteCount = i.Votes.Sum(j => j.VoteValue),
                        Reply = i
                    })
                    .ToList();

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

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