合并两个dt
C#代码中实现两个表(DataTable)的关联查询(JOIN)
之前通常都是使用SQL直接从数据库中取出表1和表2关联查询后的数据,只需要用一个JOIN就可以了,非常方便。近日遇到一种情况,两个表中的数据已经取到代码中,需要在代码中将这两个表关联起来,并得到它们横向拼在一起之后的完整数据。
如:表1--商品信息表(dtHead),存放商品的ID和名称,表结构和数据如下:

表2--商品数量及金额表(dtTail),存放商品的数量、金额,表结构和数据如下:



现在要得到表1和表2横向拼接起来的表(DtAll),结果如下:

在C#代码中,要将这两个表拼接起来,有很多笨办法,例如循环获取数据一条条拼起来,但在数据量大的情况下会影响性能,在字段多的时候也需要写一大堆给每个字段依次赋值的代码。
使用LINQ可以帮助解决这一问题。下面提供了两种方案:
方案一:当能够确定DtAll表的字段,并且字段不是很多的情况下,可以显式写出:

var query1 =
from rHead in dtHead.AsEnumerable()
from rTail in dtTail.AsEnumerable()
where rHead.Field<Int32>("GoodID") == rTail.Field<Int32>("GoodID")
select new
{
GoodID = rHead.Field<Int32>("GoodID"),
GoodName = rHead.Field<String>("GoodName"),
Num = rTail.Field<Int32>("Num"),
Money = rTail.Field<Int32>("Money")
}; DataTable dtNew = DtAll.Copy();
foreach (var obj in query1)
{
dtNew.Rows.Add(obj.GoodID, obj.GoodName, obj.Num, obj.Money);
}

其中DtAll的表结构已经事先创建好了,在下面会给出所有代码。
方案二:LINQ提供了与SQL中类似的JOIN方法。并且当字段很多的情况下,每一个字段都在select new中写出来比较麻烦,可以使用如下的方式:

var query =
from rHead in dtHead.AsEnumerable()
join rTail in dtTail.AsEnumerable()
on rHead.Field<Int32>("GoodID") equals rTail.Field<Int32>("GoodID")
select rHead.ItemArray.Concat(rTail.ItemArray.Skip(1)); foreach (var obj in query)
{
DataRow dr = DtAll.NewRow();
dr.ItemArray = obj.ToArray();
DtAll.Rows.Add(dr);
}

使用Concat将表1和表2的字段拼接起来,作为总表DtAll的字段,但由于表1、表2中都存在字段GoodID,不能在表中出现重复的字段,因此使用Skip(1)跳过表2中的第一个字段GoodID。
下面给出这个小例子完整的代码(不包括窗体,窗体上很简单,只有一个按钮)
首先写入测试数据:把表1、表2创建起来并插入如上图所示的数据(实际情况是表1、表2通过其他渠道直接获取到代码中的)
然后在单击“连接”按钮时,得到表1、表2横向连接后的表:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data; namespace WpfApplication1
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
DataTable dtHead = new DataTable();
DataTable dtTail = new DataTable();
DataTable DtAll = new DataTable(); public MainWindow()
{
InitializeComponent(); this.AddData();
} /// <summary>
/// 创建表结构,添加数据源
/// </summary>
private void AddData()
{
dtHead.Columns.Add("GoodID", typeof(Int32));
dtHead.Columns.Add("GoodName", typeof(String)); dtTail.Columns.Add("GoodID", typeof(Int32));
dtTail.Columns.Add("Num", typeof(Int32));
dtTail.Columns.Add("Money", typeof(Int32)); DtAll.Columns.Add("GoodID", typeof(Int32));
DtAll.Columns.Add("GoodName", typeof(String));
DtAll.Columns.Add("Num", typeof(Int32));
DtAll.Columns.Add("Money", typeof(Int32)); this.AddRow(1, "青岛纯生", 10, 30);
this.AddRow(2, "哈尔滨啤酒", 5, 20);
} /// <summary>
/// 添加数据
/// </summary>
/// <param name="goodID"></param>
/// <param name="goodName"></param>
/// <param name="num1"></param>
/// <param name="num2"></param>
private void AddRow(Int32 goodID, String goodName, Int32 num1,Int32 num2)
{
DataRow drH = dtHead.NewRow();
drH["GoodID"] = goodID;
drH["GoodName"] = goodName;
dtHead.Rows.Add(drH); DataRow drT = dtTail.NewRow();
drT["GoodID"] = goodID;
drT["Num"] = num1;
drT["Money"] = num2;
dtTail.Rows.Add(drT);
} /// <summary>
/// “连接”按钮单击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Join_Click(object sender, RoutedEventArgs e)
{
//方案一
var query1 =
from rHead in dtHead.AsEnumerable()
from rTail in dtTail.AsEnumerable()
where rHead.Field<Int32>("GoodID") == rTail.Field<Int32>("GoodID")
select new
{
GoodID = rHead.Field<Int32>("GoodID"),
GoodName = rHead.Field<String>("GoodName"),
Num = rTail.Field<Int32>("Num"),
Money = rTail.Field<Int32>("Money")
}; DataTable dtNew = DtAll.Copy();
foreach (var obj in query1)
{
dtNew.Rows.Add(obj.GoodID, obj.GoodName, obj.Num, obj.Money);
} //方案二
var query =
from rHead in dtHead.AsEnumerable()
join rTail in dtTail.AsEnumerable()
on rHead.Field<Int32>("GoodID") equals rTail.Field<Int32>("GoodID")
select rHead.ItemArray.Concat(rTail.ItemArray.Skip(1)); foreach (var obj in query)
{
DataRow dr = DtAll.NewRow();
dr.ItemArray = obj.ToArray();
DtAll.Rows.Add(dr);
}
}
}
}

合并两个dt的更多相关文章
- 合并两个结构完全相同的DataTable
两个结构一模一样的DataTable如何合并? 例子:使用Winform进行演示,表2的数据为固定的,表1的数据可以动态添加,通过合并按钮合并表1和表2的数据到表3 1.规定公共的DataTable结 ...
- 如何在Node.js中合并两个复杂对象
通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...
- 剑指Offer面试题:16.合并两个排序的链表
PS:这也是一道出镜率极高的面试题,我相信很多童鞋都会很眼熟,就像于千万人之中遇见不期而遇的人,没有别的话可说,唯有轻轻地问一声:“哦,原来你也在这里? ” 一.题目:合并两个排序的链表 题目:输入两 ...
- 【java基础】 合并两个类型相同的list
将两个类型相同的list合并,可以用 addAll(Collection<? extends E> c) import java.util.ArrayList; import java.u ...
- 合并两个有序数组a和b到c
问题:两个有序数组a和b,合并成一个有序数组c. // 合并两个有序数组a和b到c void Merge_Array(int a[], int n, int b[], int m, int c[]) ...
- Python合并两个numpy矩阵
numpy是Python用来科学计算的一个非常重要的库,numpy主要用来处理一些矩阵对象,可以说numpy让Python有了Matlab的味道. 实际的应用中,矩阵的合并是一个经常发生的操作,如何利 ...
- (剑指Offer)面试题17:合并两个排序的链表
题目: 输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然时按照递增排序的. 链表结点定义如下: struct ListNode{ int val; ListNode* next; }; 思 ...
- 剑指Offer15 合并两个已排序链表
/************************************************************************* > File Name: 15_MergeT ...
- java实现合并两个已经排序的列表
相对于C++来说,Java的最大特点之一就是没有令人困惑的指针,但是我们不可否认,在某些特定的情境下,指针确实算的上一把利刃.虽然Java中没有明确定义出指针,但是由于类的思想,我们可以使用class ...
随机推荐
- X-UA-Compatible
X-UA-Compatible是神马? X-UA-Compatible是IE8的一个专有<meta>属性,它告诉IE8采用何种IE版本去渲染网页,在html的<head>标签中 ...
- 怎么查看是否安装Scrapy
1.在python shell 下输入 import scrapy
- Linux系统下C语言程序的构建过程
本文转载自:http://www.ruanyifeng.com/blog/2014/11/compiler.html 源码要运行,必须先转成二进制的机器码.这是编译器的任务. 比如,下面这段源码(假定 ...
- Hive 入门学习线路指导
hive被大多数企业使用,学习它,利于自己掌握企业所使用的技术,这里从安装使用到概念.原理及如何使用遇到的问题,来讲解hive,希望对大家有所帮助. 此篇内容较多:看完之后需要达到的目标: 1.hiv ...
- python 文件操作,os.path.walk()的回调函数打印文件名
#coding=utf-8 import osdef find_file(arg,dirname,files): #for i in arg: #print i for file ...
- bzoj1643 / P2666 [Usaco2007 Oct]Bessie's Secret Pasture 贝茜的秘密草坪
[Usaco2007 Oct]Bessie's Secret Pasture 贝茜的秘密草坪 简单的dfs题 枚举前3个完全平方数,判断最后一个是不是完全平方数,统计合法方案数即可. (zz选手竟把数 ...
- PHP 开发 api 接口安全验证
原文链接:http://blog.csdn.net/li741350149/article/details/62887524
- 20165310 预备作业3 Linux安装及学习
预备作业3 Linux安装及学习 安装虚拟机 之前在win7系统下通过EasyBCD安装过Ubuntu虚拟机,这次阅读<基于VirtualBox虚拟机安装Ubuntu图文教程>又学习到了一 ...
- tf.equal的使用
tf.equal(A, B)是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,反正返回False,返回的值的矩阵维度和A是一样的 import tensorflow as tf im ...
- np.random.normal()正态分布
高斯分布的概率密度函数 numpy中 numpy.random.normal(loc=0.0, scale=1.0, size=None) 参数的意义为: loc:float 概率分布的均值,对应着整 ...