2011-03-29 24 views
11

任何人都知道我可以如何設置平均值的默認值?我有這樣一條線...Linq默認值的平均擴展方法

dbPlugins = (from p in dbPlugins 
       select new { Plugin = p, AvgScore = p.DbVersions.Average(x => x.DbRatings.Average(y => y.Score)) }) 
      .OrderByDescending(x => x.AvgScore) 
      .Select(x => x.Plugin).ToList(); 

它引發錯誤因爲我還沒有評級。如果我沒有,我想平均默認爲0.我認爲這應該是一個擴展方法,我可以指定默認值應該是什麼。

回答

-1

我嘗試了一些答案,但最終因爲某種原因得到了更多的例外。這最終爲我工作。我相信表現很好,但我會稍後再修改。

var q1 = from v in db.DbVersions select new { VersionId = v.Id, AvgScore = v.DbRatings.Average(x => x.Score) as Nullable<double> }; 
var q2 = from p in dbPlugins select new { Plugin = p, AvgScore = q1.Where(x => p.DbVersions.Select(y => y.Id).Contains(x.VersionId)).Average(x => x.AvgScore) as Nullable<double> }; 
dbPlugins = q2.OrderByDescending(x => x.AvgScore).Select(x => x.Plugin).ToList(); 
32

有:DefaultIfEmpty

我是不知道你的DbVersionsDbRatings是和哪個集合恰好具有零級的項目,但這是想法:

var emptyCollection = new List<int>(); 
var average = emptyCollection.DefaultIfEmpty(0).Average(); 

更新:(重複什麼在下面的評論說:提高知名度)

如果你發現自己需要的類類型的集合使用DefaultIfEmpty,請記住,你可以改變LINQ查詢之前聚集到項目。例如:

class Item 
{ 
    public int Value { get; set; } 
} 

var list = new List<Item>(); 
var avg = list.Average(item => item.Value); 

如果你不想/無法構造一個默認ItemValue等於0,則可以投射到的int第一個和然後集合提供一個默認的:

var avg = list.Select(item => item.Value).DefaultIfEmpty(0).Average(); 
+0

@Jon:但是現在你又回到了開始,'x.DbRatings'在這裏可以爲null。 'p.DbVersions.Select(x => x.DbRatings).DefaultIfEmpty(defaultRatings)',你需要指定'defaultRatings',它不僅僅是一個數字。 – 2011-03-29 02:26:42

0

我不認爲有一種方法來選擇默認,但如何對這個查詢

dbPlugins = (from p in dbPlugins 
      select new { 
       Plugin = p, AvgScore = 
        p.DbVersions.Any(x => x.DbRatings) ? 
         p.DbVersions.Average(x => x.DbRatings.Average(y => y.Score)) : 0 }) 
      .OrderByDescending(x => x.AvgScore) 
      .Select(x => x.Plugin).ToList(); 

基本上與您的一樣,但我們首先詢問在對它們進行平均之前是否有任何評級。如果沒有,我們返回0.