2012-03-21 2 views
0

Вот запрос:Как преобразовать случай, когда & SUM в SQL в Linq To SQL

SELECT 
    Group1 = SUM(CASE WHEN Age BETWEEN 10 AND 20 THEN 1 ELSE 0 END), 
    Group2 = SUM(CASE WHEN Age BETWEEN 21 AND 30 THEN 1 ELSE 0 END), 
    Group3 = SUM(CASE WHEN Age BETWEEN 31 AND 40 THEN 1 ELSE 0 END), 
    Group4 = SUM(CASE WHEN Age BETWEEN 41 AND 50 THEN 1 ELSE 0 END), 
    Group5 = SUM(CASE WHEN Age BETWEEN 51 AND 60 THEN 1 ELSE 0 END), 
    Group6 = SUM(CASE WHEN Age BETWEEN 61 AND 70 THEN 1 ELSE 0 END), 
    Group7 = SUM(CASE WHEN Age BETWEEN 71 AND 80 THEN 1 ELSE 0 END), 
    Group8 = SUM(CASE WHEN Age BETWEEN 81 AND 90 THEN 1 ELSE 0 END), 
    Group9 = SUM(CASE WHEN Age BETWEEN 91 AND 100 THEN 1 ELSE 0 END) 
FROM 
    (SELECT Age = DATEDIFF(yy, BirthDate, GETDATE()) 
    FROM Person 
    WHERE IsActive = 1) AgeGroup 

Что является эквивалентом Linq To SQL заявление?

Edit 1:

Ближайший я могу прийти вверх с:

var ageGroup = Persons.Select(item => DateTime.Today.Year - item.BirthDate.Value.Year) 
        .Select(age => new { 
         Group1 = age >= 10 && age <= 19 ? 1 : 0, 
         Group2 = age >= 20 && age <= 29 ? 1 : 0, 
         Group3 = age >= 30 && age <= 39 ? 1 : 0, 
         Group4 = age >= 40 && age <= 49 ? 1 : 0, 
         Group5 = age >= 50 && age <= 59 ? 1 : 0, 
         Group6 = age >= 60 && age <= 69 ? 1 : 0, 
         Group7 = age >= 70 && age <= 79 ? 1 : 0, 
         Group8 = age >= 80 && age <= 89 ? 1 : 0, 
         Group9 = age >= 90 && age <= 99 ? 1 : 0 
        }); 

var summary = new { 
       Group1 = ageGroup.Sum(item => item.Group1), 
       Group2 = ageGroup.Sum(item => item.Group2), 
       Group3 = ageGroup.Sum(item => item.Group3), 
       Group4 = ageGroup.Sum(item => item.Group4), 
       Group5 = ageGroup.Sum(item => item.Group5), 
       Group6 = ageGroup.Sum(item => item.Group6), 
       Group7 = ageGroup.Sum(item => item.Group7), 
       Group8 = ageGroup.Sum(item => item.Group8), 
       Group9 = ageGroup.Sum(item => item.Group9) 
}; 

Но это создает 9 операторы SQL.

Edit 2:

Другой способ может быть:

Persons.Select(item => DateTime.Today.Year - item.BirthDate.Value.Year) 
    .Select(age => new { 
     Group1 = age >= 10 && age <= 19 ? 1 : 0, 
     Group2 = age >= 20 && age <= 29 ? 1 : 0, 
     Group3 = age >= 30 && age <= 39 ? 1 : 0, 
     Group4 = age >= 40 && age <= 49 ? 1 : 0, 
     Group5 = age >= 50 && age <= 59 ? 1 : 0, 
     Group6 = age >= 60 && age <= 69 ? 1 : 0, 
     Group7 = age >= 70 && age <= 79 ? 1 : 0, 
     Group8 = age >= 80 && age <= 89 ? 1 : 0, 
     Group9 = age >= 90 && age <= 99 ? 1 : 0 
    }) 
    .ToList() 
    .Aggregate((previous, next) => new { 
     Group1 = previous.Group1 + next.Group1, 
     Group2 = previous.Group2 + next.Group2, 
     Group3 = previous.Group3 + next.Group3, 
     Group4 = previous.Group4 + next.Group4, 
     Group5 = previous.Group5 + next.Group5, 
     Group6 = previous.Group6 + next.Group6, 
     Group7 = previous.Group7 + next.Group7, 
     Group8 = previous.Group8 + next.Group8, 
     Group9 = previous.Group9 + next.Group9 
    }); 

Но это возвращает весь список в памяти, то вычисления суммы каждого столбца

+1

Посмотрите на эту статью, которая может вам помочь ** http: //sankarsan.wordpress.com/2010/05/16/case-statement-equivalent-in-linq/** –

+0

Он отвечает только CASE КОГДА часть моего вопроса, но спасибо в любом случае. – acermate433s

ответ

0

Почему вы хотите конвертировать абсолютно хороший запрос в Linq2Sql? Скорее всего, это пустая трата усилий.

В этом случае, вы, вероятно, лучше просто выполняет запрос и возвращает результаты:

class AgeGroupResult 
{ 
    public int Group1 { get; set; } 
    public int Group2 { get; set; } 
    // ... etc 
} 

Затем запрашивают контекст данных непосредственно:

dataContext.ExecuteQuery<AgeGroupResult>("... your SQL query ..."); 

Я думаю, что это лучше всего использовать ORM (например, Line2Sql) для управления вашими сущностями; вещи, которые вам нужно прочитать/изменить/написать. Если вам нужно извлечь данные и иметь SQL, зачем пытаться преобразовать это в выражение лямбда.

Update: Я считаю, что вы на самом деле пытаетесь сделать, это известно как карта/уменьшить, где вы первый экстракт (карта) данных, а затем уменьшить набор данных путем применения агрегатных функций. В этом случае отображение состоит из вычисления возраста, а этап уменьшения - применение функции СУММ. Linq2Sql отлично подходит для реализации картирования, но он не может иметь дело с . Уменьшить размер.

Linq (не Linq2Sql) поддерживает сокращение через функцию Aggregate, но работает только в памяти. При наилучшем решении этой проблемы с использованием Linq2Sql вы получаете набор целых чисел из базы данных, которые можно уменьшить в памяти.

Linq2Sql не предназначен для решения этой проблемы. Возможно, вы сможете расширить Linq2Sql для поддержки этого конкретного сценария, но опять же это, вероятно, будет огромная трата усилий.

Так, в ответ на ваш вопрос: нет Linq2Sql эквивалент для вашего запроса, если вам требуется, чтобы результаты были выбираемые из базы данных в одном запросе SQL и не хотите какой-либо обработки в оперативной памяти.

+0

Я просто хочу знать, возможно ли это. – acermate433s

+0

Я думал о расширении функции агрегации, но слишком много работал ни для чего. – acermate433s

-1

Я думаю, что вы просите следующий запрос

SELECT 
    SUM(CASE WHEN Age BETWEEN 10 AND 20 THEN 1 ELSE 0 END) Group1, 
    SUM(CASE WHEN Age BETWEEN 21 AND 30 THEN 1 ELSE 0 END) Group2, 
    SUM(CASE WHEN Age BETWEEN 31 AND 40 THEN 1 ELSE 0 END) Group3, 
    SUM(CASE WHEN Age BETWEEN 41 AND 50 THEN 1 ELSE 0 END) Group4, 
    SUM(CASE WHEN Age BETWEEN 51 AND 60 THEN 1 ELSE 0 END) Group5, 
    SUM(CASE WHEN Age BETWEEN 61 AND 70 THEN 1 ELSE 0 END) Group6, 
    SUM(CASE WHEN Age BETWEEN 71 AND 80 THEN 1 ELSE 0 END) Group7, 
    SUM(CASE WHEN Age BETWEEN 81 AND 90 THEN 1 ELSE 0 END) Group8, 
    SUM(CASE WHEN Age BETWEEN 91 AND 100 THEN 1 ELSE 0 END) Group9 
FROM 
    (SELECT Age = DATEDIFF(yy, BirthDate, GETDATE()) 
    FROM Person 
    WHERE IsActive = 1) AgeGroup 

это то, что вы спрашивали?

+0

Ваш ответ на самом деле является комментарием. Пожалуйста, используйте комментарии, если это необходимо –

+0

@LukasEder похоже, что это еще один вопрос: D –

+0

@huMptyduMpty .. пожалуйста, вставьте какое-то решение, чтобы я мог исправить свой ответ и улучшить свои знания .. –

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