.Distinct()调用未过滤

4

我正在尝试使用AsEnumerable将Entity Framework DbContext查询提取到IEnumerable<SelectListItem>中。这将用作模型属性,用于填充视图中的下拉列表。

然而,每个查询都会返回重复的条目,尽管已经调用了Distinct()

public IEnumerable<SelectListItem> StateCodeList { get; set; }
public IEnumerable<SelectListItem> DivCodeList { get; set; }    

DivCodeList =
    db.MarketingLookup.AsEnumerable().OrderBy(x => x.Division).Distinct().Select(x => new SelectListItem
                    {
                        Text = x.Division,
                        Value = x.Division
                    }).ToList();

StateCodeList =
    db.MarketingLookup.AsEnumerable().OrderBy(x => x.State).Distinct().Select(x => new SelectListItem
                    {
                        Text = x.State,
                        Value = x.State
                    }).ToList();
2个回答

2
为了使Distinct生效,您的序列必须包含实现IEquatable接口的类型的对象,如果该类型是自定义类型
正如这里所述:

使用默认的相等比较器通过比较值从序列中返回不同的元素。

为了避免上述问题,一种解决方法是,因为我可以得出结论,您不需要整个对象而只需要其中一个属性,将序列的每个元素投影到Division,然后进行OrderBy并调用Distinct
var divisions = db.MarketingLookup.AsEnumerable()
                                  .Select(ml=>ml.Division)
                                  .OrderBy(division=>division) 
                                  .Distinct()
                                  .Select(division => new SelectListItem
                                  {
                                     Text = division,
                                     Value = division
                                  }).ToList();

如需进一步了解,请查看此处的文档。


太棒了,感谢你的解释!一个小修改 - TextValue 只需要应用于 x,而不是 x.Division,因为 x 被赋予了我要找的值。 - NealR
@NealR 我刚看到你的评论编辑了,我已经纠正了它。非常感谢你。 - Christos

1

另一种选择(我们公司/团队经常使用的一种方法)是添加静态扩展方法(我们有一个扩展库)。

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    HashSet<TKey> seenKeys = new HashSet<TKey>();
    return source.Where(e => seenKeys.Add(keySelector(e)));
}

这可以像这样被调用;
var divisions = db.MarketingLookup.AsEnumerable().DistinctBy(d => d.PrimaryKey)
    .Select(x => new SelectListItem { Text = x.Division, Value = x.Division }).ToList();

您可以在DistinctBy()调用中使用MarketingLookup的任何属性,以便提取所需的记录。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接