2011-03-29 2 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.

Я не уверен, что ваш DbVersions и DbRatings и какие коллекции точно имеет нулевые элементы, но это идея:

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

Update: (повторять то, что сказано в комментариях ниже, чтобы увеличить видимость)

Если вам нужно использовать DefaultIfEmpty в коллекции типа класса, помните, что вы можете сменить запрос LINQ на проект до агрегации. Например:

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

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

Если вы не хотите/не можете построить по умолчанию Item с Value, равным 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', это не просто число. –

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.

 Смежные вопросы

  • Нет связанных вопросов^_^