C# 转换为字典并填写缺少的项
我的问题如下:C# 转换为字典并填写缺少的项,c#,entity-framework,C#,Entity Framework,我的问题如下: IDictionary<ClassificationLevel, Int32> stats = context.Exams .GroupBy(x => x.Classification) .Select(x => new { Key = x.Key, Count = x.Count() }) // ... public enum ClassificationLevel { L1 = 1, L2 = 2, L3 = 3, L4 = 4 }
IDictionary<ClassificationLevel, Int32> stats = context.Exams
.GroupBy(x => x.Classification)
.Select(x => new { Key = x.Key, Count = x.Count() })
// ...
public enum ClassificationLevel { L1 = 1, L2 = 2, L3 = 3, L4 = 4 }
我的问题是:
如何将查询结果转换为IDictionary
计数为0的项目将不会出现在字典中。
如何确保这些项目的值为0
更新
为了获得最佳性能,我认为应采取以下措施:
IDictionary<ClassificationLevel, Int32> stats = context.Exams
.GroupBy(x => x.Classification)
.ToDictionary(x => new { Key = x.Key, Count = x.Count() });
这将关闭EF查询
然后我会找到缺少的键,例如缺少哪些ClassificationLevel项,然后添加那些值为0的键
我该怎么做呢?您可以在LINQ中使用a,然后可以使用GroupBy+ToDictionary:
你可以这样解决
var enumValues = Enum.GetValues(typeof (EnumType)).Cast<EnumType>().ToArray();
Enumerable.Range((int) enumValues.Min(), (int) enumValues.Max()).ToDictionary(
x => x.Key,
x => context.Exams.Count(e => e.Classification == x)
);
使用,然后填写缺少的值:
IDictionary<ClassificationLevel, Int32> dict = context.Exams
.GroupBy(x => x.Classification)
.ToDictionary(g => g.Key, g => g.Count());
foreach (ClassificationLevel level in Enum.GetValues(typeof(ClassificationLevel)))
if (!dict.ContainsKey(level))
dict[level] = 0;
此代码允许您围绕枚举循环。 ClassificationLevel[]Enum.GetValuestypeofClassificationLevel中的每个ClassificationLevel级别 { }
你可以在循环的中间放一些类似的东西:
if(!stats.KeyExists(level))
{
stats.Add(level, 0);
}
使用单个linq表达式
var stats = context.Exams
.GroupBy(x => x.Classification)
.ToDictionary(x => x.Key, g => g.Count()) // execute the query
.Union(Enum.GetValues(typeof(ClassificationLevel))
.OfType<ClassificationLevel>()
.ToDictionary(x => x, x => 0)) // default empty count
.GroupBy(x => x.Key) // group both
.ToDictionary(x => x.Key, x => x.Sum(y => y.Value)); // and sum
他想要的是IDictionary,而不是匿名类型的IEnumerable。当一个新的分类被添加时会发生什么?调整了我的答案,虽然它有点直截了当。你不是为字典中的每一项计算一次吗?假设字典有20个条目,这意味着对数据库有20个查询。。。如果我错了,请纠正我。在这种情况下,您将不得不相交于2个集合,但这将是过早的优化,因为我不知道确切的情况我更新了我的问题。。。也许解决方案是从数据库中获取字典,然后填充缺少的值。对于1。@YuvalItzchakov我使用的是EF,所以考试是POCOB,但我不是这样将所有项目加载到内存中吗?如果可能的话,我想避免。。。所以应该对数据库进行计数。@MDMoura:我忽略了实体框架标记。所以我担心这对你没有帮助。我不熟悉12个实体工会不被接受。。。我收到错误:“System.Collections.Generic.Dictionary”不包含“Union”的定义,并且最佳扩展方法重载“System.Linq.Queryable.UnionSystem.Linq.IQueryable,System.Collections.Generic.IEnumerable”具有一些无效参数。你知道为什么吗?你是用x=>new{Key=x.Key,Count=x.Count}还是x=>x.Key,g=>g.Count?ToDictionary可以接受两个参数,第一个是键,第二个是值,使用两个参数应该可以很好地捕获。。。这就是问题所在。非常感谢。我正在努力找出答案。
if(!stats.KeyExists(level))
{
stats.Add(level, 0);
}
var stats = context.Exams
.GroupBy(x => x.Classification)
.ToDictionary(x => x.Key, g => g.Count()) // execute the query
.Union(Enum.GetValues(typeof(ClassificationLevel))
.OfType<ClassificationLevel>()
.ToDictionary(x => x, x => 0)) // default empty count
.GroupBy(x => x.Key) // group both
.ToDictionary(x => x.Key, x => x.Sum(y => y.Value)); // and sum