【问题标题】:Convert Dictionary<int, int?> to Dictionary<int, int> by skipping null values with LINQ通过使用 LINQ 跳过空值将 Dictionary<int, int?> 转换为 Dictionary<int, int>
【发布时间】:2012-11-19 18:12:36
【问题描述】:

我有以下Product 类:

public class Product
{
    public string Name { get; set; }
    public float Price { get; set; }     
    public int? CategoryId { get; set; }
}

现在我必须计算每个CategoryId 有多少Product,并将它们放在Dictionary&lt;int, int&gt; 中。因此:

IQueryable<Product> products = _productServices.GetAll(); //return IQueryable<Product>

Dictionary<int, int> productDict =  products.ToList()
                                            .GroupBy(p => p.CategoryId)
                                            .ToDictionary(pgroup => pgroup.key, pgroup => pgroup.Count());

问题是我从ToDictionary() 获得了Dictionary&lt;int?, int&gt;。即使我通过放置Where(p =&gt; p.CategoryId != null) 来预过滤空值,我也不会将CategoryId 的类型更改为int。我也尝试过创建匿名类型:

products.ToList()
        .GroupBy(p => p.CategoryId)
        .Select(p => new { p.key ?? -1, p.Count() }  
        .ToDictionary(pgroup => pgroup.key, pgroup => pgroup);

但它给出了Invalid anonymous type member declarator 错误。我还尝试删除 ToList() 但没有运气。我用谷歌搜索了一下,没有发现有人遇到这个问题,尽管我认为这种情况可能很常见,尤其是在使用 EFdatabases 时。有人有解决办法吗?

【问题讨论】:

  • 试试p.CategoryId.Value(不可为空)而不是p.CategoryId

标签: c# linq nullable


【解决方案1】:

那是因为CategoryId 是可空的。所以你需要先选择它的Value属性:

products.ToList()
        .Where(p => p.CategoryId.HasValue)
        .Select(p => p.CategoryId.Value)
        .GroupBy(i => i)
        .ToDictionary(g => g.Key, g => g.Count());

【讨论】:

  • +1 包括 为什么 它不起作用,而不是简单地解决它。
【解决方案2】:

简单地使用

products.ToList()
    .GroupBy(p => p.CategoryId)
    .Where(pgroup => pgroup.Key.HasValue)
    .ToDictionary(pgroup => pgroup.Key.Value, pgroup => pgroup.Count());

【讨论】:

    【解决方案3】:

    这个怎么样?

    .ToDictionary(pgroup => pgroup.Key ?? -1, pgroup => pgroup.Count());
    

    关于匿名类型的语法错误,正确的语法如下:

    .Select(p => new { Key = p.Key ?? -1, Count = p.Count() })
    

    【讨论】:

    • 小点;该操作确实明确表示“跳过空值” - 尝试包含它们很好,但您需要询问 -1 是否已经是一个有效值。
    【解决方案4】:

    需要过滤掉空值,然后使用int?.Value属性作为分组键:

    products.ToList()
            .Where(p => p.CategoryId.HasValue)
            .GroupBy(p => p.CategoryId.Value)
            .ToDictionary(pgroup => pgroup.key, pgroup => pgroup.Count());
    

    【讨论】:

      猜你喜欢
      • 2014-11-08
      • 2020-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      相关资源
      最近更新 更多