使用groupby区分基于两列的记录列表

时间:2014-08-15 09:21:02

标签: c# entity-framework list group-by distinct

我正在尝试使用EF6获取列表。我有一个这样的类:

public class Province
    {
        public string province { set; get; }
        public string provinceCode { set; get; }
    }

区域类

namespace InnoviceDomainClass
{
    using System;
    using System.Collections.Generic;

    public partial class Zone
    {
        public string CityCode { get; set; }
        public string City { get; set; }
        public string Province { get; set; }
        public Nullable<int> ProvinceCode { get; set; }
    }
}

我使用以下方式获取数据:

List<Zone> ListZone = zoneRepository.GetAll().ToList();

我需要Distinct我的记录:

   List<Province> ListZoneWithDistinct = ListZone.Select(i => new Province()
            {
                province = i.Province,
                provinceCode = i.ProvinceCode.Value.ToString()
            }).Distinct().ToList();

我认为我的问题是Distinct(),我应该根据哪个列应该区分来告诉这个函数? 但是我的记录没有改变;为什么?我的记录是相同的

我的记录是这样的

provincecode       province
10                 Iran
10                 Iran
15                 USA
15                 USA

我需要的输出:

provincecode       province
10                 Iran
15                 USA

2 个答案:

答案 0 :(得分:1)

编辑:

是的,区分您的问题,区分Lambda尝试(See it working here):

List<Province> ListZoneWithDistinct =
               ZoneList.GroupBy(x => new {x.Province, x.ProvinceCode})
               .Select(grp => new Province()
                {
                    province = grp.First().Province,
                    provinceCode = grp.First().ProvinceCode
                }).ToList();

或者您可以尝试以下LINQ / L2E:

List<Province> ListZoneWithDistinct = 
                                    (from lz in ListZone
                                     select new Province()
                                     {
                                         province = lz.Province,
                                         provinceCode = lz.ProvinceCode.Value.ToString()
                                     }).Distinct().ToList();

答案 1 :(得分:0)

您必须创建一个具有相等成员的部分类区域:

public partial class Zone
{
    protected bool Equals(Zone other)
    {
        if (ReferenceEquals(other, null))
        {
            return false;
        }

        if (ReferenceEquals(other, this))
        {
            return true;
        }

        return string.Equals(CityCode, other.CityCode) &&
               string.Equals(City, other.City) &&
               string.Equals(Province, other.Province) &&
               ProvinceCode == other.ProvinceCode;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = (CityCode != null ? CityCode.GetHashCode() : 0);
            hashCode = (hashCode*397) ^ (City != null ? City.GetHashCode() : 0);
            hashCode = (hashCode*397) ^ (Province != null ? Province.GetHashCode() : 0);
            hashCode = (hashCode*397) ^ ProvinceCode.GetHashCode();
            return hashCode;
        }
    }

    public static bool operator ==(Zone left, Zone right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(Zone left, Zone right)
    {
        return !Equals(left, right);
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Zone);
    }
}

然后,你需要一个针对Zone的IEqualityComparer实现:

public class ZoneComparer : IEqualityComparer<Zone>
{
    public bool Equals(Zone x, Zone y)
    {
        if (ReferenceEquals(x, y)) return true;

        if (ReferenceEquals(x, null) || ReferenceEquals(y, null))
            return false;

        return x.Equals(y);
    }

    public int GetHashCode(Zone product)
    {
        if (Object.ReferenceEquals(product, null)) return 0;

        return product.GetHashCode();
    }
}

之后你就可以执行这样的查询了:

        List<Province> ListZoneWithDistinct = ListZone.Distinct(new ZoneComparer()).Select(i => new Province()
        {
            province = i.Province,
            provinceCode = i.ProvinceCode.Value.ToString()
        }).ToList();