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

时间:2016-04-06 20:21:08

标签: c# linq

我有两张桌子

回复

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

和投票

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

我试图将RELIds上的两个表连接到id值,我将其作为控制器参数。

这是我使用的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

回复是

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

我有这个错误:

  

无法隐式转换类型System.Linq.IQueryable&#39;到System.Linq.IGrouping&#39;

我无法从这里出发。我需要在Votes表中使用Sum(VoteValues)并将其与Replies表连接以获取所有列值。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

您可以改为使用group join

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

根据您描述的内容,您需要获取Reply中的所有列以及所有投票的总和。这样,您可以使用匿名方式投影查询,以保存Reply实例和所需的总和。现在,您可能需要将投影保存为已知类型,因为您需要将此查询的结果传递给控制器​​。在这种情况下,我建议创建一个自定义类(也称为DTO):

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

现在您可以通过这种方式投射查询:

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

您需要考虑的另一件事是在将结果传递给视图之前实现查询:

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

答案 1 :(得分:1)

使用lambda表达式可以更简单地查询:

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