2016-12-21 13 views
1

現在、いくつかのテーブルがありますが、関連するテーブルはRestaurantReviewです。各レストランには複数のレビューがありますが、レビューにはレストランが1つしかありません。Entity Frameworkの異なるテーブルから平均を取得する

私はデータベースからレストランを検索するとき、私は各レストランのレビューの平均評価をします。

私は、指定された場所までの距離に基づいてレストランを選択します。

現在、私はここまで得ている:

public IEnumerable<Restaurant> GetRestaurantsCloseToCoords(DbGeography coordinates, int amountOfRestaurants) 
{ 
    using (var ctx = _context) 
    { 
     var data = ctx.Restaurants.OrderBy(x => x.Address.Coordinates.Distance(coordinates)) 
      .Take(amountOfRestaurants) 
      .ToList(); 

     return data; 
    } 
} 

は私のレストランのオブジェクトは、次のようになります。

public class Restaurant 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public Address Address { get; set; } 
    public List<Tag> Tags { get; set; } = new List<Tag>(); 
    public int PriceRange { get; set; } 
    public double AverageRating { get; set; } 
} 

私はforループを使用し、そのリスト内の各レストランの平均を計算することができ、しかし、私はそれが非常に遅いと確信しています。

私を助けることができる人はいますか?私はLINQでこれを保持することを好むだろうが、他のtechinquesもまあまあです!

もっと詳しく説明する必要がある場合は、事前に感謝してください!

答えて

2

Reviewsの膨大な数で、あなたが書いた最適化コードに関係なく、物事は最終的には遅くなります。

より良い方法は、Restaurantテーブルに新しい列を追加することです(AverageRating)。次に、毎日(または定期的に)実行され、この列の値を更新するコード/スクリプト(WindowsサービスまたはSQLジョブ)を作成します。あなたは、単にLINQのを使用してフィルタリングする準備ができて平均値を持っているでしょう

  1. この道を(あなたはホテルでは、その日に新しい評価を得たような様々な要因、などに基づいて、これを最適化することができます)。

  2. あなたのメソッドへの別の呼び出しがあったため、すべての平均をもう一度計算しません。
  3. 相当量のリソースがこのように保存されます。

はい、これは実装に時間がかかりますが、ええ、レストランがしかしレビューのリストを持っていない長期

+0

ありがとうございました!私はEFで多くの経験がありません。あなたが推薦/リンクできるものはありますか? – RandomStranger

+0

EFについては必ずしも必要ではありません。 C#に慣れているなら、Windowsサービスを書く方法、それをスケジュールする方法を調べるべきです。あなたは現在と同じようにデータベースと通信することができます。 – bit

+0

大丈夫、ありがとう! – RandomStranger

1
using (var ctx = _context) 
{ 
    var data = ctx.Restaurants 
      .OrderBy(x => x.Address.Coordinates.Distance(coordinates)) 
      .Take(amountOfRestaurants) 
      .Select(t=> new { Restaurant = t, Rating = ctx.Reviews.Where(c=>c.RestaurantId == t.Id).Select(c=>c.Rating).Avg()}) 
      .ToList(); 

    foreach(t in data) 
    { 
     t.Restaurant.AverageRating = t.Rating; 
    } 

    return data.Select(t=>t.Restaurant); 
} 
+0

に手で問題を解決するだろう。文脈の中で他のテーブルからそれらを取ることはできますか? – RandomStranger

+0

@Bas、ああ、私は参照してください。もう一度お待ちください – Backs

+0

@Bas smth like this – Backs

関連する問題