2014-03-05 224 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