Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 转换为字典并填写缺少的项_C#_Entity Framework - Fatal编程技术网

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