如何使用Distinct来比较我的模型类?

时间:2015-04-06 07:23:48

标签: c# asp.net asp.net-mvc

此代码在一个问题上正常运行。问题低于代码Distinct无效&数据重复。

代码

public IList<DistrictSupervisorViewModel> GetAssignedDistricts()
{
    IList<DistrictSupervisorViewModel> lsp = idistrictsupervisorrepository
            .GetList(x => x.IsActive == true && x.IsDelete == false)
            .Select(x => new DistrictSupervisorViewModel { DistrictId = x.District.DistrictId, DistrictName = x.District.DistrictName }).Distinct().ToList();
    return lsp;
}

4 个答案:

答案 0 :(得分:1)

DistrictSupervisorViewModel必须覆盖Equals和GetHashCode,你也应该实现IEquatable。请参阅此处的指南:https://msdn.microsoft.com/en-gb/library/ms173147(v=vs.80).aspx。 第二个选项是创建IEqualityComparer并将其作为Distinct方法的参数传递。这里有通用的实现:http://www.codeproject.com/Articles/94272/A-Generic-IEqualityComparer-for-Linq-Distinct

答案 1 :(得分:0)

正如@Stephen所说,请确保您的DistrictSupervisorViewModel模型类实现IEquatable

更改比较逻辑以满足您的需求。

public class DistrictSupervisorViewModel  : IEquatable<DistrictSupervisorViewModel>
{
    public bool Equals(DistrictSupervisorViewModel other)
    {
        // Do your own comparing here
        return this.DistrictId == other.DistrictId;
    }
}

答案 2 :(得分:0)

正如@Stephen和@andrepena所说,问题在于Distinct正在采用对象引用相等,从而得出结论:所有条目都是不同的。

一种解决方案是通过实现IEquality来定义不同的Equality模型,如上所述,但这使得假设将这些ViewModel之间的Equality定义为与其ID的相等性完全相同是明智的。不仅在查询中,而且无处不在! 如果的话,那么定义IEquality正是你应该做的 - 每次你使用类来解决这个问题。

但如果情况并非如此,或者您不想使用IEquatable,那么另一个选择是让Distinct-ness过滤器直接查看Id。这不能用vanilla Linq来完成,但是这个永远无价的MoreLinq包中内置了Distinctby:

var myEnumerableOfObjectsWithIds;
var output = myEnumerableOfObjectsWithIds.DistinctBy(obj => obj.Id)
在考虑ID上的相应Equality时,

output将保留不同的对象集。如果它们是值类型,那么它将使用基本值相等,如果它们是ID对象,它将使用引用类型相等(除非您实现IEquatable ......因此我们陷入循环:))

答案 3 :(得分:0)

按地区区域划分区域

public IList<DistrictSupervisorViewModel> GetAssignedDistricts()
{
    IList<DistrictSupervisorViewModel> lsp = idistrictsupervisorrepository
            .GetList(x => x.IsActive == true && x.IsDelete == false)
            .Select(x => new DistrictSupervisorViewModel { DistrictId = x.District.DistrictId, DistrictName = x.District.DistrictName }).DistinctBy(p => p.DistrictId).ToList();
    return lsp;
}