2013-07-06 105 views
0

有一个表在数据库:LINQ到SQL查询与GROUP BY

[id] [int] IDENTITY(1,1) NOT NULL, 
    [name] [varchar](150) NOT NULL, 
    [date_of_birth] [date] NOT NULL, 

我需要获得GridView控件包含2列的数据源。

---------------- 
| age || count | 
---------------- 
| 20 || 3 | 
| 21 || 4 | 
| 25 || 5 | 
---------------- 

可以用一个查询来做到吗?

我已经试过:

  var dates = (from u in db.Users 
         group u by u.date_of_birth into g 
         select new { age = calculateAge(g.Key) }).ToList(); 

      var dates1 = from d in dates 
         group d by d.age into g 
         select new { age = g.Key, count = g.Count() }; 

      GridView1.DataSource = dates1; 
      GridView1.DataBind(); 

这工作,但我觉得有一种方法,使之更加简单。或不?

P.S. calculateAge具有以下特征

private int calculateAge(DateTime date_of_birth) 

回答

1
  • 首先,你必须在第一个查询逻辑缺陷。您正在使用按日期分组,而不是按年龄分组,因此在同一年但不同日期出生的人将被分组到不同的分组中。这个'group by'被第二个查询'group by'子句取代。
  • 要注意的第二件事是您的第二个查询将使用第一个查询的实际结果(请参阅ToList()调用),以便它将在.NET上运行,而不是在SQL一侧运行。

这里是我的眼光为你查询(与同年龄人民的计数):

var dates = from u in db.Users 
    select new { age = calculateAge(g.Key) } into ages 
    group ages by ages.age into g 
    select new { age = g.Key, count = g.Count() }; 

甚至没有匿名类型声明:

var dates = from u in db.Users 
    select calculateAge(g.Key) into ages 
    group ages by ages into g 
    select new { age = g.Key, count = g.Count() }; 
+0

它给出了一个例外方法“的Int32 calculateAge(System.DateTime)'不支持对SQL的转换。 – Novikoff

+0

我对LinqToSql不是很熟悉。但我假设在你的解决方案中,首先在SQL端进行分组,并在.NET端进行选择。而在我的解决方案中,有一组是按_after_选择的。 – Aleksei