如何使用LINQ结合聚合、连接与分组计算餐厅平均评分
获取餐厅平均评分与名称的EF实现方案
嘿,我来帮你搞定这个需求!先提个小细节:你的Resteraunt类里同时定义了ICollection<Review> Reviews和Review reviews两个属性,这会导致Entity Framework的映射逻辑混乱,建议删掉单个的reviews属性,只保留集合类型的Reviews,这样一对多的关联关系才能正确生效哦。
下面是几种实用的实现方式,你可以根据自己的场景选择:
方法一:从评论表分组关联查询
这种方式适合你需要统计所有有评论的餐厅的情况,通过分组评论计算平均分,再关联餐厅表获取名称:
using System.Linq; // 假设你的DbContext包含DbSet<Resteraunt> Resteraunts和DbSet<Review> Reviews var restaurantRatings = from review in dbContext.Reviews join restaurant in dbContext.Resteraunts on review.ResterauntId equals restaurant.ResterauntId group review by new { restaurant.ResterauntId, restaurant.Name } into ratingGroup select new { RestaurantId = ratingGroup.Key.ResterauntId, RestaurantName = ratingGroup.Key.Name, AverageRating = ratingGroup.Average(r => r.Rating) }; // 转为列表获取结果 var resultList = restaurantRatings.ToList();
方法二:从餐厅表利用导航属性查询(更直观)
因为你的Resteraunt类已经有了Reviews导航属性,直接从餐厅表入手会更简洁,还能轻松处理无评论的餐厅:
var restaurantRatings = dbContext.Resteraunts .Select(restaurant => new { restaurant.ResterauntId, restaurant.Name, // 处理无评论的情况,默认返回0分 AverageRating = restaurant.Reviews.Average(r => (double?)r.Rating) ?? 0.0 }) .ToList();
只查询特定餐厅ID的情况
如果只需要获取某一个餐厅的平均分和名称,加上Where过滤即可:
int targetRestaurantId = 5; // 替换成你要查询的ID var targetRestaurant = dbContext.Resteraunts .Where(r => r.ResterauntId == targetRestaurantId) .Select(r => new { r.ResterauntId, r.Name, AverageRating = r.Reviews.Average(review => (double?)review.Rating) ?? 0.0 }) .FirstOrDefault();
这些查询都会在数据库层面完成分组和计算,性能表现很好,不用担心内存处理的问题。
内容的提问来源于stack exchange,提问作者Curious-programmer
相关产品推荐
相关产品推荐

