返回LINQ的平均值列表

时间:2014-03-05 18:28:16

标签: c# asp.net sql asp.net-mvc linq

我正在尝试在我的餐厅评论网站上建议。它获得某个餐厅的所有评论的平均分数,然后找到与原始餐厅具有相同美食的所有其他餐厅的平均评价分数。它返回一个餐厅列表,这些餐厅的菜肴与原始餐厅的评论平均值相同。然后它将列表保存到数据库中。

我尝试在linq中创建查询,但我一直在接收Cannot implicitly convert type 'System.Collections.Generic.List<int>' to 'int'等错误或查询结果错误。

任何帮助都会很棒。

错误行

var getrestaurantaverage = db.Reviews
    .Where(r => r.RestaurantId = getrestaurantsid)
    .Average(r => r.score);

建议功能

var averagescore = db.Reviews
    .Where(r => r.RestaurantId == review.RestaurantId)
    .Average(r => r.score);

var getrestaurantsid = (from r in db.Reviews
                       where r.Cuisine == review.Cuisine
                       select r.RestaurantId).ToList();
var getrestaurantaverage = db.Reviews
    .Where(r => r.RestaurantId = getrestaurantsid)
    .Average(r => r.score);

var choices = (from r in db.Reviews
               where getrestaurantaverage >= averagescore
               select r.RestaurantId).ToList();
foreach (var item in choices)
{
    var suggestion = new Suggestion()
    {
        reviewid = review.id,
        Userid = review.UserId,
        restaurantid = item
    };
    db.Suggestions.Add(suggestion);
    db.SaveChanges();
}

return RedirectToAction("Index", "Review");

4 个答案:

答案 0 :(得分:2)

好像你正在进行太多的DB调用以获取所有必要的数据。您应该尝试将所有这些查询合并为一个:

from r in db.Reviews
where r.Cuisine == review.Cuisine
group r by r.RestaurantId into g
where g.Average(x => x.Score) >= db.Reviews.Where(r => r.RestaurantId == review.RestaurantId).Average(x => x.Score)
select g.Key

答案 1 :(得分:1)

.Where(r => r.RestaurantId = getrestaurantsid)尝试将int ID与列表进行比较。如果要查找ID在列表中的resturants,请执行以下操作:

var getrestaurantaverage = db.Reviews
    .Where(r => getrestaurantsid.Contains(r.RestaurantId))
    .Average(r => r.score);

要获得每个餐厅的平均值,您可以创建一个匿名类型

var getrestaurantaverage = db.Reviews
    .Where(r => getrestaurantsid.Contains(r.RestaurantId))
    .GroupBy(r => r.RestaurantId)
    .Select(g => new { ID = g.Key, Average = g.Average(r => r.score) });

foreach (var x in getrestaurantaverage) {
    Console.WriteLine("Restaurant = {0}, average = {1}", x.ID, x.Average);
}

这为您提供每个餐厅ID的平均值。


然而,没有必要事先获得餐馆ID列表,直接进行

var getrestaurantaverage = db.Reviews
    .Where(r => r.Cuisine == review.Cuisine)
    .GroupBy(r => r.RestaurantId)
    .Select(g => new { ID = g.Key, Average = g.Average(r => r.score) });

答案 2 :(得分:1)

所以你的代码问题就在这里:

.Where(r => r.RestaurantId = getrestaurantsid)

getrestaurantsid是一个值列表而非一个值。

我们可以改变这一点,但你的问题更重要。 getrestaurantaverage不能只是一个查询,使用您的一般方法,您需要执行此操作,* getrestaurantsid中的每个ID:

foreach var restaurantID in getrestaurantsid)
{
    var getrestaurantaverage = db.Reviews.Where(r => r.RestaurantId = getrestaurantsid).Average(r => r.score);

    var choices = (from r in db.Reviews
                   where getrestaurantaverage >= averagescore
                   select r.RestaurantId).ToList();
    foreach (var item in choices)
    {
        var suggestion = new Suggestion()
        {
            reviewid = review.id,
            Userid = review.UserId,
            restaurantid = item
        };
        db.Suggestions.Add(suggestion);
        db.SaveChanges();
    }

}

但这 super 效率低下。您现在正在执行不同数据库查询的批次批次。我们可以简化整个事情 lot

var reviewAverages = db.Reviews.Where(r => r.Cuisine == review.Cuisine)
    .GroupBy(r => r.RestaurantId)
    .ToDictionary(group => group.Key, group => group.Average(r => r.score);

var myAverage = reviewAverages[review.RestaurantId];
var choices = reviewAverages.Where(pair => pair.Value >= myAverage);

就是这样。一个单独的数据库查询,只有几行代码。

答案 3 :(得分:0)

您的问题在这里:

var getrestaurantsid = (from r in db.Reviews
                       where r.Cuisine == review.Cuisine
                       select r.RestaurantId).ToList();
var getrestaurantaverage = db.Reviews.Where(r => r.RestaurantId = getrestaurantsid).Average(r => r.score);

getrestaurantsid的类型为List<int>,因此下面的Where函数中的表达式无效。

我建议更像这样的事情:

var getrestaurantaverage = db.Reviews.Where(r => getrestaurantsid.Contains(r.RestaurantId)).Average(r => r.score);