c#实现两个(DataTable)数据合并

Posted yheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#实现两个(DataTable)数据合并相关的知识,希望对你有一定的参考价值。

在C#代码中,要将这两个表拼接起来,也有很多比较“笨”的办法,就是例如循环获取数据一条条拼起来,此办法在数据量少、字段少的可以使用此办法,但在数据量大的情况下会影响性能,而且字段多的时候也需要写一大堆给每个字段依次赋值的代码,性能就有所下降,下列将介绍合并DataTable的几种方法

主要介绍三种方案

方案一【For循环+RowFilter】

 1             dt_All.Rows.Clear();
 2             dgvResult.DataSource = dt_All;
 3             //方案一:For循环
 4             for (int i = 0; i < dt_Head.Rows.Count; i++)
 5             {
 6                 DataRow drAll = dt_All.NewRow();
 7                 drAll["StockID"] = dt_Head.Rows[i]["StockID"];
 8                 drAll["ProductName"] = dt_Head.Rows[i]["ProductName"];
 9                 DataView dv = new DataView(dt_Detail);
10                 dv.RowFilter = string.Format("StockID = ‘{0}‘", dt_Head.Rows[i]["StockID"]);
11                 DataTable dtDetail = dv.ToTable();
12                 if (dtDetail.Rows.Count > 0)
13                 {
14                     drAll["Num"] = dtDetail.Rows[0]["Num"];
15                     drAll["Money"] = dtDetail.Rows[0]["Money"];
16                 }
17                 dt_All.Rows.Add(drAll);
18             }
19             dgvResult.DataSource = dt_All;

 

方案二【适合字段比较少的情况下。】

 1             dt_All.Rows.Clear();
 2             dgvResult.DataSource = dt_All;
 3             //方案二:字段少的情况下
 4             var Little = from rHead in dt_Head.AsEnumerable()
 5                          from rDetail in dt_Detail.AsEnumerable()
 6                          where rHead.Field<int>("StockID") == rDetail.Field<int>("StockID")
 7                          select new
 8                          {
 9                              StockID = rHead.Field<int>("StockID"),
10                              ProductName = rHead.Field<string>("ProductName"),
11                              Num = rDetail.Field<int>("Num"),
12                              Money = rDetail.Field<decimal>("Money"),
13                          };
14             DataTable dtNew = dt_All.Copy();
15             foreach (var obj in Little)
16             {
17                 dtNew.Rows.Add(obj.StockID, obj.ProductName, obj.Num, obj.Money);
18             }
19             dgvResult.DataSource = dtNew;

方案三【LINQ提供了与SQL类型的JOIN类似的方法,并且字段比较多的情况下,可使用如下方式。】

 1             dt_All.Rows.Clear();
 2             dgvResult.DataSource = dt_All;
 3             //方案三:字段多的情况下
 4             var query =
 5                 from rHead in dt_Head.AsEnumerable()
 6                 join rDetail in dt_Detail.AsEnumerable()
 7                 on rHead.Field<Int32>("StockID") equals rDetail.Field<Int32>("StockID")
 8                 select rHead.ItemArray.Concat(rDetail.ItemArray.Skip(1));
 9 
10             foreach (var obj in query)
11             {
12                 DataRow dr = dt_All.NewRow();
13                 dr.ItemArray = obj.ToArray();
14                 dt_All.Rows.Add(dr);
15             }
16             dgvResult.DataSource = dt_All;

使用Concat将表1和表2的字段拼接起来,作为总表dt_All的字段,但由于表1、表2中都存在字段StockID,不能在表中出现重复的字段,因此使用Skip(1)跳过表2中的第一个字段StockID。

 

完整代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class FrmDemo : Form
    {
        DataTable dt_Head = new DataTable();
        DataTable dt_Detail = new DataTable();
        DataTable dt_All = new DataTable();
        public FrmDemo()
        {
            InitializeComponent();
            InitData();
        }

        private void InitData()
        {
            dt_Head.Columns.Add("StockID", typeof(Int32));
            dt_Head.Columns.Add("ProductName", typeof(String));

            dt_Detail.Columns.Add("StockID", typeof(Int32));
            dt_Detail.Columns.Add("Num", typeof(Int32));
            dt_Detail.Columns.Add("Money", typeof(decimal));

            dt_All.Columns.Add("StockID", typeof(Int32));
            dt_All.Columns.Add("ProductName", typeof(String));
            dt_All.Columns.Add("Num", typeof(Int32));
            dt_All.Columns.Add("Money", typeof(decimal));

            for (int i = 1; i < 10; i++)
            {
                DataRow dr_Head = dt_Head.NewRow();
                DataRow dr_Detail = dt_Detail.NewRow();
                dr_Head["StockID"] = i;
                dr_Head["ProductName"] = "商品" + i;

                dr_Detail["StockID"] = i;
                dr_Detail["Num"] = i;
                dr_Detail["Money"] = i * 0.5;

                dt_Head.Rows.Add(dr_Head);
                dt_Detail.Rows.Add(dr_Detail);
            }
        }

        private void btnFor_Click(object sender, EventArgs e)
        {
            dt_All.Rows.Clear();
            dgvResult.DataSource = dt_All;
            //方案一:For循环
            for (int i = 0; i < dt_Head.Rows.Count; i++)
            {
                DataRow drAll = dt_All.NewRow();
                drAll["StockID"] = dt_Head.Rows[i]["StockID"];
                drAll["ProductName"] = dt_Head.Rows[i]["ProductName"];
                DataView dv = new DataView(dt_Detail);
                dv.RowFilter = string.Format("StockID = ‘{0}‘", dt_Head.Rows[i]["StockID"]);
                DataTable dtDetail = dv.ToTable();
                if (dtDetail.Rows.Count > 0)
                {
                    drAll["Num"] = dtDetail.Rows[0]["Num"];
                    drAll["Money"] = dtDetail.Rows[0]["Money"];
                }
                dt_All.Rows.Add(drAll);
            }
            dgvResult.DataSource = dt_All;
        }

        private void btnLittle_Click(object sender, EventArgs e)
        {
            dt_All.Rows.Clear();
            dgvResult.DataSource = dt_All;
            //方案二:字段少的情况下
            var Little = from rHead in dt_Head.AsEnumerable()
                         from rDetail in dt_Detail.AsEnumerable()
                         where rHead.Field<int>("StockID") == rDetail.Field<int>("StockID")
                         select new
                         {
                             StockID = rHead.Field<int>("StockID"),
                             ProductName = rHead.Field<string>("ProductName"),
                             Num = rDetail.Field<int>("Num"),
                             Money = rDetail.Field<decimal>("Money"),
                         };
            DataTable dtNew = dt_All.Copy();
            foreach (var obj in Little)
            {
                dtNew.Rows.Add(obj.StockID, obj.ProductName, obj.Num, obj.Money);
            }
            dgvResult.DataSource = dtNew;
        }

        private void btnMore_Click(object sender, EventArgs e)
        {
            dt_All.Rows.Clear();
            dgvResult.DataSource = dt_All;
            //方案三:字段多的情况下
            var query =
                from rHead in dt_Head.AsEnumerable()
                join rDetail in dt_Detail.AsEnumerable()
                on rHead.Field<Int32>("StockID") equals rDetail.Field<Int32>("StockID")
                select rHead.ItemArray.Concat(rDetail.ItemArray.Skip(1));

            foreach (var obj in query)
            {
                DataRow dr = dt_All.NewRow();
                dr.ItemArray = obj.ToArray();
                dt_All.Rows.Add(dr);
            }
            dgvResult.DataSource = dt_All;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            dt_All.Rows.Clear();
            dgvResult.DataSource = dt_All;
        }
    }
}

 

以上是关于c#实现两个(DataTable)数据合并的主要内容,如果未能解决你的问题,请参考以下文章

c# 两个datatable合并

C#如何将两个DataTable Row合并为一行

c#中同一个Datatable中的如何把重复的记录合并起来,

2个DataTable的合并问题!! 急!!!!!!!!!

c# datatable 相邻数据去重?

c#中两个列名相同的datatable,如何将他们数据加到一起?