从实体框架中的不同表中获取平均值

时间:2016-12-21 10:58:50

标签: c# linq

我目前有几个表,但相关的表是Reviewpublic 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; }
}

我的餐馆对象如下:

{{1}}

我可以使用for循环计算该列表中每家餐馆的平均值,但我很确定它很慢。

有没有人可以帮助我?我更喜欢将它保留在LINQ中,但其他技术也完全没问题!

请提前告知我是否应该详细说明!

2 个答案:

答案 0 :(得分:2)

有大量的Reviews,无论你编写什么优化代码,事情最终会变慢。

更好的方法是在Restaurant表中添加一个名为AverageRating的新列。然后编写一段每天(或定期)运行的代码/脚本(Windows服务或sql作业)并更新此列中的值。 (您可以根据各种因素对此进行优化,例如,哪家酒店当天获得了新评级等)

这样:

  1. 您可以准备仅使用Linq过滤平均值。
  2. 您不会再次计算所有平均值,只是因为您的方法有另一个调用。
  3. 因此可以节省大量资源。
  4. 是的,实施这将耗费时间,但是,是的,可以长期解决手头的问题

答案 1 :(得分: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);
}