你如何转换一个案例& SQL中的SUM到Linq To SQL

时间:2012-03-21 16:04:45

标签: sql linq

以下是查询:

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语句?

修改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语句。

编辑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
    });

但是这会将整个列表检索到内存,然后计算每列的SUM

2 个答案:

答案 0 :(得分:0)

为什么要将完美的查询转换为Linq2Sql? 这很可能是浪费精力。

在这种情况下,您最好只执行查询并返回结果:

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

然后直接查询数据上下文:

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

我认为最好使用ORM(如Line2Sql)来管理您的实体;你需要阅读/修改/写的东西。如果您需要提取数据并拥有SQL,为什么还要尝试将其转换为lambda表达式。

<强>更新 我相信你实际上要做的事情被称为map / reduce,你首先提取(映射)数据,然后通过应用聚合函数来减少数据集。在这种情况下,映射包括计算年龄,而reduce阶段是SUM函数的应用。 Linq2Sql非常适合实现映射部分,但它不能处理 reduce 部分。

Linq(不是Linq2Sql)支持通过Aggregate函数进行缩减,但它仅在内存中运行。使用Linq2Sql解决此问题的最佳案例解决方案是从数据库中获取一组可以减少内存的整数。

Linq2Sql不是针对此类问题而设计的。您可能能够扩展Linq2Sql以支持这种特定情况,但同样可能会浪费大量精力。

所以,回答你的问题:如果你需要在单个SQL查询中从数据库中提取结果并且不需要任何内存,那么查询没有Linq2Sql等效处理

答案 1 :(得分:-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

你问的是什么?