Linq to DataTable 合并结构相同的 个DataTable 且已重复的行不合并


可能标题有点绕口,先看一下需求:

有两个结构相同的DataTable 
分别为dtA,dtB : 

dtA
 
1 a
 
2 b 
3 c 
3 c 
3 b 
5 a 


dtB 
1 a 
1 b 
2 b 
5 a 
6 c 

把dtA的数据添加到dtB里,只要dtB中没有的就都要添加到dtB里 
结果如下:

合并后 
dtC
 
1 a 
1 b 
2 b 
3 c 
3 c 
3 b 
5 a 
6 c 

仔细分析后发现dtA内有两条重复的数据 3 c 都要添加到 dtB内,这点要注意

实现思路:

l   先找出要添加到 dtB内的数据 即:存在于dtA却不存在于dtB内的DataRow:({3 c} {3 c} {3 b}

l   将找到的数据与dtB中记录合并并排序

l   添加到dtC中

 //第一步 先初始化数据

                DataTable dtA = new DataTable();

                dtA.Columns.Add("id"typeof(int));

                dtA.Columns.Add("name"typeof(string));

                dtA.Rows.Add(1, "a");

                dtA.Rows.Add(2, "b");

                dtA.Rows.Add(3, "c");

                dtA.Rows.Add(3, "c");

                dtA.Rows.Add(3, "b");

                dtA.Rows.Add(5, "a");

                DataTable dtB = dtA.Clone();

                dtB.Rows.Add(1, "a");

                dtB.Rows.Add(1, "b");

                dtB.Rows.Add(2, "b");

                dtB.Rows.Add(5, "a");

                dtB.Rows.Add(6, "c");

//第二步:找出要添加到 dtB内的数据即:存在于dtA却不存在于dtB内的DataRow:({3 c} {3 c} {3 b}

 var query = dtA.AsEnumerable().Except(dtB.AsEnumerable(), DataRowComparer.Default);

//我们先来看看query内的结果是什么:

 query.ToList().ForEach(c => Console.WriteLine(string.Format("{0}/t{1}/t", c.ItemArray[0], c.ItemArray[1])));

                /*

                3  c   

                3  b

                */

 

将结果打印出来后,我们发现结果中只有两行,少了一行 3 c,于是我们要这样来得到我们想要的结果:

   var query = from a in dtA.AsEnumerable() 
                   where dtB.AsEnumerable().Where(b=>a.Field<int>("id")==b.Field<int>("id") 
                    && a.Field<string>("name")==b.Field<string>("name")).Count()==0 
                     select a;       

    //我们再来看看query内的结果是什么:此时就是我们想要的结果了

   query.ToList().ForEach(c => Console.WriteLine(string.Format("{0}/t{1}/t", c.ItemArray[0], c.ItemArray[1])));

                /*

               3   c   

               3   c   

               3   b

                */

 

接下来就是最后一步合并query 和dbB,得到最终想要的dtC,完整代码如下:

 

void Main()

{

      DataTable dtA=new DataTable();

     dtA.Columns.Add("id",typeof(int));

     dtA.Columns.Add("name",typeof(string));

     dtA.Rows.Add(1,"a");

     dtA.Rows.Add(2,"b");

     dtA.Rows.Add(3,"c");

     dtA.Rows.Add(3,"c");

     dtA.Rows.Add(3,"b");

     dtA.Rows.Add(5,"a");

    

     DataTable dtB=dtA.Clone();

     dtB.Rows.Add(1,"a");

     dtB.Rows.Add(1,"b");

     dtB.Rows.Add(2,"b");

     dtB.Rows.Add(5,"a");

     dtB.Rows.Add(6,"c");

    

     var query=(from a in dtA.AsEnumerable() 
                  where dtB.AsEnumerable().Where(b=>a.Field<int>("id")==b.Field<int>("id"
                   && a.Field<string>("name")==b.Field<string>("name")).Count()==0 
                   select a).Concat(dtB.AsEnumerable()).OrderBy(o=>o.Field<int>("id"));

      

      DataTable dtC=dtA.Clone();

      query.ToList().ForEach(q=>dtC.Rows.Add(q.ItemArray));

      Console.WriteLine("id/tname/t");

      dtC.AsEnumerable().ToList().ForEach(c=>Console.WriteLine(string.Format("{0}/t{1}/t",c.ItemArray[0],c.ItemArray[1])));

      

     /*

     id    name   

     1    a   

     1    b   

     2    b   

     3    c   

     3    c   

     3    b   

     5    a   

     6    c

     */

      

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值