如何在ASP.NET中对QueryExpression/ObservableCollection结果做Count()与分组?
在Dynamics CRM 365的ASP.NET程序中实现QueryExpression/ObservableCollection的计数与分组
当然可以用LINQ来搞定你的需求!而且我们有两种主流方案可选——直接在CRM服务器端通过QueryExpression做聚合统计(性能最优,推荐大数据量场景),或者拿到ObservableCollection后在客户端用LINQ处理(灵活度高,适合小数据量或复杂逻辑)。下面给你一步步拆解:
方案一:服务器端通过QueryExpression实现分组+计数(推荐)
QueryExpression本身支持聚合(Aggregate)和分组(GroupBy)操作,让CRM服务器直接处理统计逻辑,减少客户端和服务器之间的数据传输量,性能更好。
举个实际例子:假设我们要统计不同账户类型(字段new_accounttype)的客户数量,代码如下:
// 1. 创建QueryExpression,指定要查询的实体(这里是account) var query = new QueryExpression("account") { // 不需要返回实体的所有字段,只需要分组和统计相关的 ColumnSet = new ColumnSet(false) }; // 2. 添加分组规则:按new_accounttype字段分组 query.GroupBy.Add(new GroupByColumn("new_accounttype")); // 3. 添加聚合统计:统计每组的数量,别名设为"account_count" query.Aggregations.Add(new AggregateExpression( AggregateType.Count, "accountid", // 用主键来计数,避免重复 "account_count" )); // 4. 执行查询,拿到结果 var result = service.RetrieveMultiple(query); // 5. 解析统计结果 foreach (var entity in result.Entities) { var accountType = entity.GetAttributeValue<OptionSetValue>("new_accounttype")?.Value.ToString(); var count = entity.GetAttributeValue<int>("account_count"); Console.WriteLine($"账户类型 {accountType} 的数量:{count}"); }
注意:CRM支持的聚合类型有
Count、Sum、Avg、Min、Max等;分组字段可以是选项集、文本、数值等类型,但要确保字段是可分组的。
方案二:客户端通过LINQ处理ObservableCollection
如果已经把QueryExpression的结果转换成了ObservableCollection<Entity>,我们可以直接用LINQ的GroupBy和Count()方法来实现分组统计,非常灵活。
示例代码如下:
// 假设这是你从CRM拿到的ObservableCollection<Entity> var accountCollection = new ObservableCollection<Entity>(service.RetrieveMultiple(query).Entities); // 用LINQ分组并统计数量 var groupedResult = accountCollection .GroupBy(account => account.GetAttributeValue<OptionSetValue>("new_accounttype")?.Value) // 过滤掉分组键为null的情况(如果有账户没设置类型) .Where(g => g.Key != null) .Select(g => new { AccountTypeId = g.Key, AccountCount = g.Count() }) .ToList(); // 如果需要转换成XML格式,可以用LINQ to XML var xml = new XElement("AccountStats", from item in groupedResult select new XElement("AccountType", new XAttribute("Id", item.AccountTypeId), new XElement("Count", item.AccountCount) ) ); // 输出XML Console.WriteLine(xml.ToString());
小提示:如果你的实体有强类型的类(比如通过Early Bound生成的),代码会更简洁,不用
GetAttributeValue,直接访问属性即可。
两种方案的对比
- 服务器端方案:性能高,适合大数据量,减少网络传输,但聚合规则受CRM支持的类型限制。
- 客户端方案:灵活度高,可以实现复杂的分组逻辑,但需要先把所有数据拉到客户端,数据量大时性能会受影响。
内容的提问来源于stack exchange,提问作者autopenta
相关产品推荐
相关产品推荐

