2014-03-05 157 views
0

我想在我的餐厅评论网站上提出一个建议系统。它得到某家餐厅所有评论的平均分数,然后找到所有其他餐厅的平均评分,这些餐厅与原始餐厅有相同的美食。它会返回一份餐厅列表,其中的餐厅评分平均值高于原始餐厅。然后它将列表保存到数据库中。返回平均值列表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"); 
+0

哪条线给你一个错误? – MarcinJuraszek

回答

1

.Where(r => r.RestaurantId = getrestaurantsid)试图与列表进行比较的int ID。如果你想找到resturants ID分别在列表中,这样做:

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

会给你所有餐馆的平均放在一起。 – MarcinJuraszek

+0

“getrestaurantsid”列表中包含的所有餐馆,因为“Average”会获得由前面的Where所过滤的枚举。 –

+0

我如何得到每个餐厅的平均水平? – Dolaps

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); 
+0

会给你所有餐馆的平均放在一起。 – MarcinJuraszek

+0

@MarcinJuraszek我认为这是OP所期待的。 –

+0

这显然是错误的假设。 – MarcinJuraszek

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,因为这个查询比我的要好一些。我不会删除我的答案,因为这个答案不能解释为什么OP的代码不起作用。 – Servy

1

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

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

getrestaurantsid是一个值列表不是一个值。

我们可以改变这一点,但你的问题更重要。getrestaurantaverage不能只是一个查询,您的一般方法,你需要做的是,*每个ID在getrestaurantsid

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

} 

但这超级效率低下。您现在正在执行不同DB查询的批次批次。我们可以简化这整个事情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); 

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

+0

不检查'美食'的平等。也可以在应用程序中获得所有的平均值,当然你也可以在DB上使用'> = myAverage'。 – MarcinJuraszek

+0

@MarcinJuraszek对,编辑。 – Servy