【问题标题】:Finding Average of value based on count of rows in LINQ根据 LINQ 中的行数查找平均值
【发布时间】:2013-07-31 23:58:35
【问题描述】:

我有一个餐厅评论应用程序,它有一个单独的餐厅和评论表。我已经构建了一个 MVC WebAPI,它有一个基于餐厅 ID 传递餐厅对象的方法。

作为返回对象的一部分,我想添加一个平均评分值,该值基于在评论表中输入的评分值的总和除以餐厅 ID 输入的评论总数.

如果值是一位小数的格式,那就太好了。

我可以使用以下代码从评论表中获取平均值(没有小数位)

var sum = (from a in db.Reviews
           where a.ReviewsRestaurantID.Equals(id)
           select a.ReviewsRating).Sum();

var count = (from a in db.Reviews
             where a.ReviewsRestaurantID.Equals(id)
             select a.ReviewsRating).Count();

decimal average = sum / count;

我不确定如何将值添加到用于按 ID 方法返回餐厅的查询中(请参见下文)。有人可以帮助将自定义平均评分值添加到下面的方法中,还是有办法在评论表上进行连接并更有效地计算值?

public IQueryable<Restaurant> GetRestaurantByID(int id)
{ 
  var query = from a in db.Restaurants
              where a.RestaurantID.Equals(id)
              select a;

  return query; 
}

【问题讨论】:

    标签: c# linq asp.net-mvc-4 asp.net-web-api


    【解决方案1】:

    对于初学者,您可以真正减少您的代码 + 到服务器的流量。既然你提到了表、行和数据库,我猜你会去一些 SQL 服务器。

    首先从服务器获取您关心的所有内容,即

    var reviews = (from x in db.Reviews where a.ReviewsRestaurantID.Equals(id) select x).ToList();
    

    现在您不必两次单独访问服务器来收集您关心的数据。您可以对现在内存中的数据运行和“平均”查询...

    // Assuming, from your sample that the ratings are stored as decimals....
    // This will do the counting, summing, dividing, etc.
    decimal avg = (from x in reviews select x.Rating).Average();
    

    【讨论】:

    • 你不限于id
    【解决方案2】:
    var resReviews = from x in db.Restaurants 
                     join y in db.Reviews on x.RestaurantID equals y.ReviewsRestaurantID into z 
                     from a in z
                     group a by a.RestaurantID into g 
                     select new {
                        RestaurantInfo = g.FirstOrDefault(),
                        RatingAverage = g.Average(x=>x.ReviewsRating)
                     };
    

    【讨论】:

    • 完全错过的餐厅和评论在我的回答中有所不同。
    • @Hogan 你说的missed Restaurants 是什么意思?此查询返回所有餐厅的所有信息,包括平均评分,只需添加一些 where 即可获取特定餐厅信息。
    • 你没有阅读我的评论——我说在我的回答中——并为你投票。
    • 谢谢大家。我实施了这个解决方案并让它发挥作用。我唯一的问题是 RestaurantInfo 变量返回 Review 对象而不是 Restaurant 对象。有没有办法纠正这个问题?我尝试了几种方法,但都不成功
    • @Piranha86 你可以从RestaurantInfo获取RestaurantReview的信息,我不知道你的Restaurant有什么属性,你可以在初始化新的Restaurant最后一个select 而不是RestaurantInfo 就像Restaurant = new Restaurant(...), 而不是RestaurantInfo = g.FirstOrDefault()(), 但是你仍然需要g.FirstOrDefault() 来获取Restaurant 的属性。
    【解决方案3】:

    你可以只使用平均值:

    var average = (from a in db.Reviews
                   where a.ReviewsRestaurantID.Equals(id)
                   select a.ReviewsRating).Average();
    

    你也可以用这样的聚合来做(如果你真正想做的更复杂,这里是平均值的示例实现):

    var result = db.Reviews.Where(r => r.ReviewsRestaurantID = id)
         .Aggregate(new () { total = 0, count = 0, avg = 0.0 },
              (o, n) => {
                 var result = new () { total = o.total+n.ReviewsRating, count = o.count+1, avg = 0.0};
                 result.avg = result.total / result.count;
                 return result;
           }, (r) => r.avg);
    

    【讨论】:

      猜你喜欢
      • 2021-12-22
      • 2020-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-09
      • 1970-01-01
      相关资源
      最近更新 更多