使用LINQ聚合对象

时间:2013-04-05 08:19:38

标签: c# entity-framework-4 linq-to-entities

我有SQL查询来获取块数,按块名分组

var sql = @"select count(*) [COUNT], o.NAME from WISH w
                            left join objects o on o.ID = w.[BLOCKID]
                            where w.ISDELETE = 0
                            group by o.NAME"
var cmd = new SqlCommand(sql, connection);
var reader = cmd.ExecuteReader();
Label labelClear = (Label)Master.FindControl("labelClear");

if (reader.HasRows)
{
   while (reader.Read())
   {
      labelClear.Text += reader["NAME"].ToString() + " - " + reader["COUNT"].ToString() + "; ";
   }
 }

使输出字符串像:

"BLOCKNAME1 - 15; BLOCKNAME2 - 3; BLOCKNAME3 - 28" etc.

(其中15,3和28--计算BLOCKNAME1,BLOCKNAME2和BLOCKNAME3)。

我尝试将此查询转换为LINQ:

((Label)Master.FindControl("labelClear")).Text = 
Db.WISH.Where(x => x.ISDELETE == 0)
.GroupBy(x => x.OBJECTS_BLOCK.NAME)
.Select(g => new { Name = g.Key, Cnt =  SqlFunctions.StringConvert((decimal?)g.Count()) })
.Aggregate((a, b) => a.Name + ": " + a.Cnt + ", " + b.Name + ": " + b.Cnt );

但是在最后一行得到错误(使用Aggregate):

Cannot implicitly convert type 'string' to 'AnonymousType#2'

将结果聚合到字符串中的正确方法是什么

"BLOCKNAME1 - 15; BLOCKNAME2 - 3; BLOCKNAME3 - 28"

1 个答案:

答案 0 :(得分:3)

尝试一下:

((Label)Master.FindControl("labelClear")).Text = 
Db.WISH.Where(x => x.ISDELETE == 0)
.GroupBy(x => x.OBJECTS_BLOCK.NAME)
.Select(g => new { Name = g.Key, Cnt =  SqlFunctions.StringConvert((decimal?)g.Count()) })
.AsEnumerable()
.Aggregate(string.Empty, (a, b) => a + ", " + b.Name + ": " + b.Cnt, s => s.Substring(2));

Aggregate参数说明:

  • string.Empty - 初始种子值
  • (a, b) => a + ", " + b.Name + ":" + b.Cnt - 聚合功能。它将当前种子值与新值字符串连接起来。
  • s => s.Substring(2) - 结果选择功能。删除前2个字符,这是不必要的,

AsEnumerable是将字符串连接从DB移动到应用程序所必需的。 EF不支持使用该参数的Aggregate方法。 Count()仍然由DB执行。