Помогите со следующим запросом linq? - PullRequest
0 голосов
/ 03 марта 2010

Возьмите следующий запрос linq:

var summary = results.Select(r => 
                             new
                             {
                             TotalPopulation = results.Sum(s => s.Population),
                             TotalGross = results.Sum(s => s.Gross),
                             }).Distinct();

Выше работает нормально, но это лучший способ сделать это. Что представляет собой r? Зачем мне это нужно?

Кроме того, я думаю, что я мог бы добавить следующее к моему запросу, но я не могу:

GrossPerPop = TotalPopulation / TotalGross

Выше сказано, что TotalPopulation и Total Gross не существуют в текущем контексте.

Я тоже пробовал:

GrossPerPop = results.sum(s => s.Population) / results.Sum(s => s.Gross), 

Вышесказанное говорит / не может быть применено к десятичной дроби? или двойной? Это как-то связано с тем, что поля обнуляются? Так получилось, что у меня нет полей Population или Gross с нулевым значением, поэтому я изменил их на необнуляемые поля в конструкторе таблиц sql. Однако, если они содержат значение 0, как я могу проверить это в коде Linq?

Ответы [ 2 ]

3 голосов
/ 03 марта 2010

Лучший способ это что-то вроде:

class Metrics {
    public int TotalPopulation { get; set; }
    public decimal TotalGross { get; set; }
    public decimal GrossPerPopulation {
        get {
            return TotalGross / TotalPopulation;
        }
    }
 }

Тогда:

var metrics = new Metrics {
                  TotalPopulation = results.Sum(s => s.Population), 
                  TotalGross = results.Sum(s => s.Gross)
              };

В настоящее время у вас есть выполнение вышеуказанной проекции (хотя и в анонимном виде) для каждого элемента results, а затем выбрасывание всех, кроме одной, результирующей проекции. Вы можете обойтись без создания явного типа, как я делал выше, и просто использовать анонимный тип, но это было бы глупо.

Что означает r?

r представляет имя параметра в анонимном методе, который вы определили.

Зачем мне это нужно?

Когда вы пишете

results.Select(expression)

необходимо, чтобы expression был делегатом, который питается независимо от типа элементов results и возвращает какой-то другой тип. То есть IEnumerable<SomeType>.Select для проецирования последовательности в другую последовательность. Следовательно, вы должны передать метод, который поедает любой тип элементов results и возвращает какой-то другой тип. Один из способов сделать это - передать анонимного делегата. Одним из способов определения анонимного делегата является использование лямбда-выражения. Когда вы говорите r => ..., вы определяете анонимный метод с помощью лямбда-выражения.

Кроме того, я думаю, что я мог бы добавить следующее к моему запросу, но я не могу:

GrossPerPop = TotalPopulation / TotalGross

Это верно, вы не можете. Думайте об этом так. Скажем, у вас был явный тип

class Metrics {
    public int TotalPopulation { get; set; }
    public decimal TotalGross { get; set; }
    public decimal GrossPerPopulation { get; set; }
    public Metrics(
        int totalPopulation,
        decimal totalGross,
        decimal grossPerPopulation
    ) {
            TotalPopulation = totalPopulation;
            TotalGross = totalGross;
            GrossPerPopulation = grossPerPopulation;
    }
}

Должно ли следующее быть законным?

Metrics m = new Metrics(100, 100, m.TotalPopulation / m.TotalGross)

Конечно нет! Но это именно то, что вы пытаетесь сделать.

GrossPerPop = results.Sum(s => s.Population) / results.Sum(s => s.Gross)

Выше указано, что / нельзя применить к десятичной дроби? или двойной?

Я не вижу причин, чтобы вы получали такое сообщение. В C # вышеприведенное является законным, если предположить, что s.Population и s.Gross являются числовыми типами; они просто будут неявно повышены до «правильного» типа. Это верно, даже если s.Population или s.Gross являются числовыми типами.

Обратите внимание, однако, что брутто на население должно быть

results.Sum(s => s.Gross) / results.Sum(s => s.Population)
2 голосов
/ 03 марта 2010

Это не очень хороший запрос, потому что сумма будет рассчитываться для каждой строки, а затем будет «отличной».

Просто напишите

var summary = new
   {
      TotalPopulation = results.Sum(s => s.Population),
      TotalGross = results.Sum(s => s.Gross),
   };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...