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人の政治家がいる可能性があります。データベースをループ
で最大7回呼び出すのは費用がかかりますか?foreachこれはベストプラクティスではないことを知っているので、この特定のケースでそれを回避し、データベースを1回呼び出してから、サーバー側で処理する方法はありますか?

4

2 に答える 2

2

更新-ユーザーのコメントにより、サーバー上での集約を確実にするために再調整されました。この場合、サーバー上で両方IDPoliticianでグループ化し、次にグループをローカルでIDAttributeプルすることができます。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 })

レガシー-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つのクエリである必要があります(NewsToPoliticiansdbに依存するかどうかによって異なります)。試してみてください。

于 2012-12-04T16:39:40.910 に答える
1

ストアドプロシージャを使用して、SQLサーバーエンジンにすべての作業を実行させます。引き続きLinqを使用してストアドプロシージャを呼び出すことができます。これにより、データベースへのすべての呼び出しが最小限に抑えられます。

于 2012-12-04T15:36:07.240 に答える