我正在尝试按以下数据集计算按名称分组的唯一Foos和Bars.
Id | IsActive | Name | Foo | Bar
1 | 1 | A | 11 | null
2 | 1 | A | 11 | null
3 | 1 | A | null | 123
4 | 1 | B | null | 321
Run Code Online (Sandbox Code Playgroud)
我希望上面数据的结果是:
Expected:
A = 2;
B = 1;
Run Code Online (Sandbox Code Playgroud)
我尝试按名称,Foo,Bar进行分组,然后再按名称分组,并使用计数来获取"行"计数.但那并没有给我正确的结果.(或者ToDictionary扔了一个重复的键,我玩了很多,所以不记得了)
db.MyEntity
.Where(x => x.IsActive)
.GroupBy(x => new { x.Name, x.Foo, x.Bar })
.GroupBy(x => new { x.Key.Name, Count = x.Count() })
.ToDictionary(x => x.Key, x => x.Count);
Run Code Online (Sandbox Code Playgroud)
所以我提出了这个LINQ查询.但它相当慢.
db.MyEntity
.Where(x => x.IsActive)
.GroupBy(x => x.Name)
.ToDictionary(x => x.Key,
x =>
x.Where(y => y.Foo != null).Select(y => y.Foo).Distinct().Count() +
x.Where(y => y.Bar != null).Select(y => y.Bar).Distinct().Count());
Run Code Online (Sandbox Code Playgroud)
我该如何优化它?
这是推荐的实体
public class MyEntity
{
public int Id { get; set; }
public bool IsActive { get; set; }
public string Name { get; set; }
public int? Foo { get; set; }
public int? Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我也试过这个查询
db.MyEntity
.Where(x => x.IsActive)
.GroupBy(x => new { x.Name, x.Foo, x.Bar })
.GroupBy(x => x.Key.Name)
.ToDictionary(x => x.Key, x => x.Count());
Run Code Online (Sandbox Code Playgroud)
但那引发了超时异常:(
该查询效率极低,因为您在客户端完成大部分工作(构建字典所涉及的所有工作),而无法使用数据库进行投影。这是一个问题,因为数据库(特别是如果这些值被索引)可以比客户端更快地完成这项工作,而且还因为在数据库上进行投影涉及通过网络发送的数据少得多。
因此,只需在对数据进行分组之前进行预测即可。
var activeItems = db.MyEntity.Where(x => x.IsActive);
var query = activeItems.Select(x => new { Name, Value = x.Foo}).Distinct()
.Concat(activeItems.Select(x => new { Name, Value = x.Bar}).Distinct())
.Where(x => x != null)
.GroupBy(pair => pair.Name)
.Select(group => new { group.Key, Count = Group.Count()})
.ToDictionary(pair => pair.Key, pair => pair.Count);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1264 次 |
| 最近记录: |