简体   繁体   English

从Entity Framework中的不同表格获取平均值

[英]Getting averages from different table in Entity Framework

I currently have several tables, but the relevant ones are Restaurant and Review . 我目前有几个表,但相关的表是RestaurantReview Each restaurant can have multiple reviews, but a review has only 1 restaurant. 每个餐厅可以有多个评论,但一个评论只有1个餐厅。

Now when I retrieve restaurants from the database, I want their average rating from the reviews on each restaurant. 现在,当我从数据库中检索餐馆时,我希望从每个餐馆的评论中获得它们的平均评分。

I select the restaurants based on distance to a given location. 我根据到给定位置的距离选择餐厅。

Currently, I have gotten this far: 目前,我已经做到了:

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

My restaurant object looks like this: 我的餐厅对象如下所示:

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

I can use a for loop and calculate an average for each restaurant in that list, but I'm pretty sure it's very slow. 我可以使用for循环并为该列表中的每个餐厅计算平均值,但是我敢肯定它的速度非常慢。

Is there anyone who could help me? 有谁可以帮助我吗? I'd prefer to keep this in LINQ, but other techinques are totally fine, too! 我宁愿将此保留在LINQ中,但其他技术也完全可以!

Let me know if I should elaborate more, thanks in advance! 让我知道是否需要详细说明,在此先感谢!

With huge number of Reviews , no matter what optimized code you write, things will slow down eventually. 拥有大量的Reviews ,无论您编写什么优化代码,事情最终都会变慢。

A better approach would be to add a new column to the Restaurant table, called AverageRating . 更好的方法是在Restaurant表中添加一个名为AverageRating的新列。 Then write a piece of code/script (a windows service or sql job) that runs daily (or periodically) and updates the values in this column. 然后编写一段每天(或定期)运行的代码/脚本(Windows服务或sql作业)并更新此列中的值。 (You may optimize this based on various factors like, which hotel got new ratings on that day, etc) (您可以根据多种因素对此进行优化,例如当天哪家酒店获得了新的评价等等)

This way: 这条路:

  1. You would have averages ready to merely filter using a Linq. 您将准备好平均值,仅使用Linq进行过滤。
  2. You would not calculate all the averages again, simply because there was another call to your method. 您不会再次计算所有平均值,仅是因为有另一个方法调用。
  3. A significant amount resources would be thus saved. 这样可以节省大量资源。

Yes, this would be time consuming to implement, but yeah, would solve the issue at hand in long term 是的,这将很耗时实施,但是,是的,它将长期解决当前的问题

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM