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

时间:2012-11-19 10:07:55

标签: c# linq nullable

我有以下Product课程:

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

现在我必须计算每个Product的{​​{1}}个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());

问题是我从Dictionary<int?, int>获得ToDictionary()。即使我通过放置Where(p => 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()但没有运气。虽然我认为这种情况可能很频繁,特别是在使用 EF 数据库时,我会稍微谷歌一点,但我没有发现任何人有这个问题。有人有解决方案吗?

4 个答案:

答案 0 :(得分: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());

答案 1 :(得分:5)

只需使用

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

答案 2 :(得分:4)

这个怎么样?

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

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

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

答案 3 :(得分:0)

您需要过滤掉空值,然后使用.Value的{​​{1}}属性作为分组键:

int?