1

我目前有这个代码:

foreach (var newsToPolitician in news.NewsToPoliticians)
{
     var politician = newsToPolitician.Politician;
     var votes = (from s in db.Scores
                   where o.IDPolitician == politician.IDPolitician
                         && o.IDNews == IDNews
                   group o by o.IDAtribute
                   into g
                   select new{
                      Atribute= g.Key,
                      TotalScore= g.Sum(x => x.Score)
                   }).ToList();
}

它工作正常,但我想避免foreach循环对我的数据库进行多次查询。我的表Scores如下所示:

IDScore | IDNews | IDUser | IDPolitician | IDAtribute | Score
1         40       1010     35             1             1
2         40       1010     35             2            -1
3         40       1002     35             1             1
4         40       1002     35             2             1
5         40       1002     40             1            -1
...

我的目标是汇总新闻中所有政客的所有分数。一条新闻最多可以有 7 个政客。在一个循环
中调用我的数据库多达七次是否很昂贵。foreach我知道这不是最佳实践,所以我很感兴趣有没有办法在这种特殊情况下避免它并调用数据库然后在服务器端处理它?

4

2 回答 2

2

更新 - 由于用户评论已重新调整以尝试并确保在服务器上进行聚合。在这种情况下,我们可以通过两者在服务器上进行分组IDPoliticianIDAttribute然后将这些组拉入ToLookup本地,如下所示:

var result = db.Scores.Where(s => s.IDNews == IDNews)
                      .Where(s => news.NewsToPoliticians
                                      .Select(n => n.Politician.IDPolitician)
                                      .Contains(s.IDPolitician))
                      .GroupBy(s => new
                                    {
                                      s.IDPolitician,
                                      s.IDAttribute
                                    },
                                (k,g ) => new
                                          {
                                           k.IDPolitician,
                                           k.IDAttribute,
                                           Sum = g.Sum(x => x.Score)
                                           })
                      .ToLookup(anon => anon.IDPolitician,
                                anon => new { anon.IDAttribute, anon.Sum })

Legacy - 你想在GroupJoin这里使用,它会是这样的:

var result = news.NewsToPoliticians
                 .GroupJoin( db.Scores.Where(s= > s.IDNews == IDNews),
                             p => p.IDPolitician,
                             s => s.IDPolitician,
                             (k,g) => new
                                      {
                                        PoliticianId = k,
                                        GroupedVotes = g.GroupBy(s => s.IDAtribute,
                                                                 (id, group) => new
                                                                                {
                                                                                 Atribute = id,
                                                                                 TotalScore = group.Sum(x => x.Score)
                                                                                 })
                                      })
                 .ToList();

但是,您的提供者将如何翻译它,因此您可能仍然需要多个查询来解决这个问题,您可以使用以下内容:

var politicianIds = news.NewsToPoliticians.Select(p => p.IDPolitician).ToList()
var result = db.Scores.Where(s= > s.IDNews == IDNews)
                      .Where(s => politicianIds.Contains(s.IDPolitician))
                      .GroupBy(p => p.IDPolitician,
                              (k,g) => new
                                       {
                                        PoliticianId = k,
                                        GroupedVotes = g.GroupBy(s => s.IDAtribute,
                                                                 (id, group) => new
                                                                                {
                                                                                 Atribute = id,
                                                                                 TotalScore = group.Sum(x => x.Score)
                                                                                 })
                                       })
                      .ToList();

希望最多应该是 2 个查询(取决于是否NewsToPoliticians依赖于 db)。你只需要试试看。

于 2012-12-04T16:39:40.910 回答
1

使用存储过程并让 SQL 服务器引擎完成所有工作。您仍然可以使用 Linq 调用存储过程,这将最大限度地减少对数据库的所有调用

于 2012-12-04T15:36:07.240 回答