• .net Distinct 去重问题分析


    问题:.net中的distinct方法对于自定义的类(class model )去重时失效。问题分析:

    model1:

    1  public class TestModel1
    2     {
    3         public int Id { get; set; }
    4         public string Name { get; set; }
    5         public string Address { get; set; }
    6     }

    model2:

     public class TestModel2
        {
            protected bool Equals(TestModel2 other)
            {
                return Id == other.Id && string.Equals(Name, other.Name) && string.Equals(Address, other.Address);
            }
    
            public override int GetHashCode()
            {
                unchecked
                {
                    int hashCode = Id;
                    hashCode = (hashCode*397) ^ (Name != null ? Name.GetHashCode() : 0);
                    hashCode = (hashCode*397) ^ (Address != null ? Address.GetHashCode() : 0);
                    return hashCode;
                }
            }
    
            public int Id { get; set; }
            public string Name { get; set; }
            public string Address { get; set; }
            public override bool Equals(object obj)
            {
                if (ReferenceEquals(null, obj)) return false;
                if (ReferenceEquals(this, obj)) return true;
                if (obj.GetType() != this.GetType()) return false;
                return Equals((TestModel2) obj);
            }
        }

    Model3:

     public class TestModel3
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Address { get; set; }
            
        }
    
        public class ListTestModel3 : IEqualityComparer<TestModel3>
        {
            public bool Equals(TestModel3 x, TestModel3 y)
            {
                if (x.Id == y.Id && x.Name == y.Name && x.Address == y.Address)
                {
                    return true;
                }
                return false;
            }
    
            public int GetHashCode(TestModel3 obj)
            {
                return 0;
            }
        }

    主程序:

      1   public partial class Form1 : Form
      2     {
      3         public Form1()
      4         {
      5             InitializeComponent();
      6             InitData();
      7 
      8         }
      9 
     10         private void InitData()
     11         {
     12 
     13             var model1s = new List<TestModel1>();
     14             var model2s = new List<TestModel2>();
     15             var model3s = new List<TestModel3>();
     16             for (int i = 0; i < 3; i++)
     17             {
     18                 var model1 = new TestModel1()
     19                     {
     20                         Id = 10001,
     21                         Name = "张三",
     22                         Address = "中国-上海"
     23                     };
     24                 var model2 = new TestModel2()
     25                     {
     26                         Id = 10001,
     27                         Name = "张三",
     28                         Address = "中国-上海"
     29                     };
     30                 var model3 = new TestModel3()
     31                     {
     32                         Id = 10001,
     33                         Name = "张三",
     34                         Address = "中国-上海"
     35                     };
     36                 model1s.Add(model1);
     37                 model2s.Add(model2);
     38                 model3s.Add(model3);
     39             }
     40 
     41             for (int i = 0; i < 3; i++)
     42             {
     43                 var model1 = new TestModel1()
     44                     {
     45                         Id = 10002,
     46                         Name = "张三",
     47                         Address = "中国-上海"
     48                     };
     49                 var model2 = new TestModel2()
     50                     {
     51                         Id = 10002,
     52                         Name = "张三",
     53                         Address = "中国-上海"
     54                     };
     55                 var model3 = new TestModel3()
     56                     {
     57                         Id = 10002,
     58                         Name = "张三",
     59                         Address = "中国-上海"
     60                     };
     61                 model1s.Add(model1);
     62                 model2s.Add(model2);
     63                 model3s.Add(model3);
     64             }
     65             for (int i = 0; i < 3; i++)
     66             {
     67                 var model1 = new TestModel1()
     68                     {
     69                         Id = 10001,
     70                         Name = "李四",
     71                         Address = "中国-上海"
     72                     };
     73                 var model2 = new TestModel2()
     74                     {
     75                         Id = 10001,
     76                         Name = "李四",
     77                         Address = "中国-上海"
     78                     };
     79                 var model3 = new TestModel3()
     80                     {
     81                         Id = 10001,
     82                         Name = "李四",
     83                         Address = "中国-上海"
     84                     };
     85                 model1s.Add(model1);
     86                 model2s.Add(model2);
     87                 model3s.Add(model3);
     88             }
     89             for (int i = 0; i < 3; i++)
     90             {
     91                 var model1 = new TestModel1()
     92                     {
     93                         Id = 10002,
     94                         Name = "李四",
     95                         Address = "中国-上海"
     96                     };
     97                 var model2 = new TestModel2()
     98                     {
     99                         Id = 10002,
    100                         Name = "李四",
    101                         Address = "中国-上海"
    102                     };
    103                 var model3 = new TestModel3()
    104                     {
    105                         Id = 10002,
    106                         Name = "李四",
    107                         Address = "中国-上海"
    108                     };
    109                 model1s.Add(model1);
    110                 model2s.Add(model2);
    111                 model3s.Add(model3);
    112             }
    113             var model4s = (from m in model1s
    114                            select new TestModel1
    115                                {
    116                                    Id = m.Id,
    117                                    Name = m.Name,
    118                                    Address = m.Address
    119                                }).ToList().Distinct();
    120             dataGridView1.DataSource = model1s;
    121             dataGridView2.DataSource = model2s;
    122             dataGridView3.DataSource = model3s;
    123             dataGridView4.DataSource = model4s.ToList(); ;
    124         }
    125 
    126         private void InitDistinctData()
    127         {
    128 
    129             var model1s = new List<TestModel1>();
    130             var model2s = new List<TestModel2>();
    131             var model3s = new List<TestModel3>();
    132             for (int i = 0; i < 3; i++)
    133             {
    134                 var model1 = new TestModel1()
    135                     {
    136                         Id = 10001,
    137                         Name = "张三",
    138                         Address = "中国-上海"
    139                     };
    140                 var model2 = new TestModel2()
    141                     {
    142                         Id = 10001,
    143                         Name = "张三",
    144                         Address = "中国-上海"
    145                     };
    146                 var model3 = new TestModel3()
    147                     {
    148                         Id = 10001,
    149                         Name = "张三",
    150                         Address = "中国-上海"
    151                     };
    152                 model1s.Add(model1);
    153                 model2s.Add(model2);
    154                 model3s.Add(model3);
    155             }
    156 
    157             for (int i = 0; i < 3; i++)
    158             {
    159                 var model1 = new TestModel1()
    160                     {
    161                         Id = 10002,
    162                         Name = "张三",
    163                         Address = "中国-上海"
    164                     };
    165                 var model2 = new TestModel2()
    166                     {
    167                         Id = 10002,
    168                         Name = "张三",
    169                         Address = "中国-上海"
    170                     };
    171                 var model3 = new TestModel3()
    172                     {
    173                         Id = 10002,
    174                         Name = "张三",
    175                         Address = "中国-上海"
    176                     };
    177                 model1s.Add(model1);
    178                 model2s.Add(model2);
    179                 model3s.Add(model3);
    180             }
    181             for (int i = 0; i < 3; i++)
    182             {
    183                 var model1 = new TestModel1()
    184                     {
    185                         Id = 10001,
    186                         Name = "李四",
    187                         Address = "中国-上海"
    188                     };
    189                 var model2 = new TestModel2()
    190                     {
    191                         Id = 10001,
    192                         Name = "李四",
    193                         Address = "中国-上海"
    194                     };
    195                 var model3 = new TestModel3()
    196                     {
    197                         Id = 10001,
    198                         Name = "李四",
    199                         Address = "中国-上海"
    200                     };
    201                 model1s.Add(model1);
    202                 model2s.Add(model2);
    203                 model3s.Add(model3);
    204             }
    205             for (int i = 0; i < 3; i++)
    206             {
    207                 var model1 = new TestModel1()
    208                     {
    209                         Id = 10002,
    210                         Name = "李四",
    211                         Address = "中国-上海"
    212                     };
    213                 var model2 = new TestModel2()
    214                     {
    215                         Id = 10002,
    216                         Name = "李四",
    217                         Address = "中国-上海"
    218                     };
    219                 var model3 = new TestModel3()
    220                     {
    221                         Id = 10002,
    222                         Name = "李四",
    223                         Address = "中国-上海"
    224                     };
    225                 model1s.Add(model1);
    226                 model2s.Add(model2);
    227                 model3s.Add(model3);
    228             }
    229             var model4s = (from m in model1s
    230                            select new 
    231                            {
    232                                Id = m.Id,
    233                                Name = m.Name,
    234                                Address = m.Address
    235                            }).ToList().Distinct();
    236             dataGridView1.DataSource = model1s.Distinct().ToList();
    237             dataGridView2.DataSource = model2s.Distinct().ToList();
    238             dataGridView3.DataSource = model3s.Distinct(new ListTestModel3()).ToList();
    239             dataGridView4.DataSource = model4s.ToList();
    240         }
    241 
    242         private void button1_Click(object sender, EventArgs e)
    243         {
    244             InitDistinctData();
    245 
    246         }

    过滤前结果:

    过滤后结果:

    分析:model1不管过滤前和过滤后均没有去重,model2 重写了Equals 和GetHashCode两个方法,过滤前后结果不一样, model3实现了IEqualityComparer接口进行了Distinct时重写Equals 和GetHashCode两个方法。效果和model2是一样的。Model4,去重之前用的是自己定义的实体类,框架不知道相等的条件,顾虽然去重但是没有效果,过滤后Model4采用了匿名方法类,简单的匿名类型内部实际是键值对,框架内部使用默认的相等比较器对值进行比较,所以可以去重。

    结论:自定义类无法实现多键值去重(Distinct),可以通过以上三种方法去实现。

    Demo:下载

  • 相关阅读:
    c++ 图解快速排序算法
    Shell脚本检测文件夹是否已被挂载的方法
    Linux使用mount挂载samba共享
    PHP使用字符串名称调用类的方法
    命令行查看端口号被进程占用
    Golang Clearing slice
    送给自己的程序员箴言
    Entity Framework6 with Visual Studio 2013 update3 for Oracle 11g
    深入浅出ASP.NET MVC5系列之一
    年终福利:调试.NET Framework源代码
  • 原文地址:https://www.cnblogs.com/caosenianhuan/p/3867718.html
Copyright © 2020-2023  润新知