我的查询如下:
IDictionary<ClassificationLevel, Int32> stats = context.Exams
.GroupBy(x => x.Classification)
.Select(x => new { Key = x.Key, Count = x.Count() })
// ...
字典ClassificationLevel如下:
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的那些键。
我该怎么做?
答案 0 :(得分:1)
使用Enumerable.ToDictionary()
然后Enum.GetValues()
填写缺失的值:
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;
或者,如果实体框架在ToDictionary()
处发布,我相信您可以执行以下操作:
IDictionary<ClassificationLevel, Int32> dict = context.Exams
.GroupBy(x => x.Classification)
.Select(x => new { Key = x.Key, Count = x.Count() })
.AsEnumerable()
.ToDictionary(g => g.Key, g => g.Count);
foreach (ClassificationLevel level in Enum.GetValues(typeof(ClassificationLevel)))
if (!dict.ContainsKey(level))
dict[level] = 0;
答案 1 :(得分:1)
使用单个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
答案 2 :(得分:0)
您可以在LINQ中使用"Left Outer Join",之后您可以使用GroupBy
+ ToDictionary
:
var query = from classification in Enum.GetValues(typeof(ClassificationLevel)).Cast<ClassificationLevel>()
join exam in context.Exams on classification equals exam.Classification into gj
from subExam in gj.DefaultIfEmpty()
select new { classification, exam = subExam };
IDictionary<ClassificationLevel, Int32> stats = query
.GroupBy(x => x.classification)
.ToDictionary(g => g.Key, g => g.Count());
答案 3 :(得分:0)
你可以像这样解决它
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)
);
答案 4 :(得分:0)
此代码允许您循环枚举。 foreach(ClassificationLevel级别在(ClassificationLevel [])Enum.GetValues(typeof(ClassificationLevel))) { }
然后你可以在循环中间添加如下内容:
if(!stats.KeyExists(level))
{
stats.Add(level, 0);
}