在另一个表上使用嵌套查询查找平均值
本文关键字:嵌套 查询 查找 平均值 另一个 | 更新日期: 2023-09-27 18:28:12
我有一个常见的问题,我无法通过查看互联网上的几个论坛来解决。
我有一个使用ASP.NET WebAPI的餐厅评级应用程序。该应用程序有两张桌子Restaurant和Comments桌子。每个餐厅可能有多条评论,每条评论都有一个评级值。我正试图在WebAPI中组合一种方法,通过查看Comments表,从Restaurant表中提取详细信息,以及每个Restaurants的Average Rating值。到目前为止,我的尝试是在下面的代码中,但它不起作用。我尝试过使用聚合函数、平均函数、嵌套查询、联接等,但仍然无法获取平均值。如果有人能帮忙,我会很感激的?
public IQueryable<RestaurantView> GetRestaurants(string All)
{
var query = from x in db.Restaurants
select new RestaurantView
{
RestaurantID = x.RestaurantID,
RestaurantName = x.RestaurantName,
RestaurantDecription = x.RestaurantDecription
RestaurantRatingAverage = (from a in db.Restaurants
join b in db.Comments on a.RestaurantID equals b.CommentsRestaurantID into z
from c in z
group c by c.CommentsRestaurantID into g
select new
{
RatingAverage = Convert.ToDouble(g.Average(a => a.CommentsRating))
};)
};
return query;
}
更新:使用Jonathan的技术(见下文)
public IQueryable<RestaurantView> GetRestaurants(string All)
{
var query = from x in db.Restaurants
select new RestaurantView
{
RestaurantID = x.RestaurantID,
RestaurantName = x.RestaurantName,
RestaurantDecription = x.RestaurantDecription,
RestaurantRatingAverage = (from a in db.Comments
where a.CommentsRestaurantID.Equals(x.RestaurantID)select a.CommentsRating).Average()
};
return query;
}
但我现在得到以下异常
An error has occurred.","ExceptionMessage":"The cast to value type 'Double' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type."
下面是一个可以在LINQPad 中执行的示例
EDIT:更新以显示子查询的null处理
void Main()
{
var restaurants = new List<Restaurant>();
restaurants.Add(new Restaurant(1, "McDonalds"));
restaurants.Add(new Restaurant(2, "Wendy's"));
restaurants.Add(new Restaurant(3, "KFC"));
var comments = new List<Comment>();
comments.Add(new Comment(1, 1, "I love clowns!", 9.5));
comments.Add(new Comment(2, 1, "Disgusting", 1.0));
comments.Add(new Comment(3, 1, "Average", 5.0));
comments.Add(new Comment(4, 2, "Hmmm tasty", 8.5));
comments.Add(new Comment(5, 2, "Yuck", 4.0));
// Edit - removed comment for KFC, updated code below to handle nulls
var restaurantsWithRatings = restaurants.Select(r => new {
RestaurantId = r.RestaurantId,
Name = r.Name,
Rating = (
comments.Where(c => c.RestaurantId == r.RestaurantId)
.Select(c => c.Rating)
.DefaultIfEmpty(0)
).Average()
});
foreach(var r in restaurantsWithRatings)
Console.WriteLine("{0}: {1}", r.Name, r.Rating);
}
class Restaurant
{
public Restaurant(int restaurantId, string name)
{
RestaurantId = restaurantId;
Name = name;
}
public int RestaurantId { get; set; }
public string Name { get; set; }
}
class Comment
{
public Comment(int commentId, int restaurantId, string message, double rating)
{
CommentId = commentId;
RestaurantId = restaurantId;
Message = message;
Rating = rating;
}
public int CommentId { get; set; }
public int RestaurantId { get; set; }
public string Message { get; set; }
public double Rating { get; set; }
}