c#实现两个(DataTable)数据合并
2018-02-08 13:56
791 查看
在C#代码中,要将这两个表拼接起来,也有很多比较“笨”的办法,就是例如循环获取数据一条条拼起来,此办法在数据量少、字段少的可以使用此办法,但在数据量大的情况下会影响性能,而且字段多的时候也需要写一大堆给每个字段依次赋值的代码,性能就有所下降,下列将介绍合并DataTable的几种方法
使用Concat将表1和表2的字段拼接起来,作为总表dt_All的字段,但由于表1、表2中都存在字段StockID,不能在表中出现重复的字段,因此使用Skip(1)跳过表2中的第一个字段StockID。
主要介绍三种方案
方案一【For循环+RowFilter】
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;
方案二【适合字段比较少的情况下。】
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;
方案三【LINQ提供了与SQL类型的JOIN类似的方法,并且字段比较多的情况下,可使用如下方式。】
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;
使用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; } } }
相关文章推荐
- AutoCAD.Net/C#.Net QQ群:193522571 将DataTable集合 B加入到DataTable A中,应用于两个或以上的只有单行数据的无主键的datatable的合并 Merge
- 如何在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- C#中同一DataTable中合并相同条件的行数据
- 311530 HOW TO:在 Visual C# .NET 中使用 System.Xml 合并两个 XML 文档中的数据 (From MKBA)
- 如果在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- [转]如何在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- c# 对两个Datatable的结构相同进行合并
- sql server之触发器调用C#CLR存储过程实现两个表的数据同步
- C#开发之DataTable多行数据的合并
- 如何在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- C# 向DataTable中插入伪造DataTable数据及实现DataTable行列转换
- C#/.NET 条件合并两个DataTable
- 如何在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- [转载]:合并两个已排序好的int数组,并排序返回c#实现
- 如何在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- 在NET 1.1中合并两个DataTable的简单实现
- c# 对两个Datatable的结构相同进行合并
- Asp.net C# 使用Newtonsoft.Json 实现DataTable转Json格式数据
- HOW TO:在 Visual C# .NET 中使用 System.Xml 合并两个 XML 文档中的数据
- 在NET 1.1中合并两个DataTable的简单实现