通过使用LINQ跳过空值,将Dictionary <int,int?>转换为Dictionary <int,int>

Cic*_*ami 3 c# linq nullable

我有以下Product课程:

public class Product
{
    public string Name { get; set; }
    public float Price { get; set; }     
    public int? CategoryId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在我必须计算Product每个人有多少CategoryId并将它们放入一个Dictionary<int, int>.因此:

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());
Run Code Online (Sandbox Code Playgroud)

问题是,我得到一个Dictionary<int?, int>ToDictionary().即使我通过放置预过滤空值Where(p => p.CategoryId != null)我不改变CategoryIdto 的类型int.我还尝试创建和匿名类型:

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

但它给出了一个Invalid anonymous type member declarator错误.我也试图删除ToList()但没有运气.我稍微谷歌了,我没有发现任何人有这个问题,虽然我认为这种情况可能很频繁,特别是在使用EF数据库时.有人有解决方案吗?

Tim*_*ter 7

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

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

  • +1包括*为什么*它不起作用,而不是简单地解决它. (2认同)

Tho*_*que 5

这个怎么样?

.ToDictionary(pgroup => pgroup.Key ?? -1, pgroup => pgroup.Count());
Run Code Online (Sandbox Code Playgroud)

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

.Select(p => new { Key = p.Key ?? -1, Count = p.Count() })
Run Code Online (Sandbox Code Playgroud)


Raw*_*ing 5

简单地使用

products.ToList()
    .GroupBy(p => p.CategoryId)
    .Where(pgroup => pgroup.Key.HasValue)
    .ToDictionary(pgroup => pgroup.Key.Value, pgroup => pgroup.Count());
Run Code Online (Sandbox Code Playgroud)