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()); 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(, "青岛纯生", , );
this.AddRow(, "哈尔滨啤酒", , );
} /// <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()); foreach (var obj in query)
{
DataRow dr = DtAll.NewRow();
dr.ItemArray = obj.ToArray();
DtAll.Rows.Add(dr);
}
}
}
}



C#代码中实现两个表(DataTable)的关联查询(JOIN)的更多相关文章
- 关于表 datatable的条件查询
关于表 datatable的条件查询 从数据库中获得一个datatable dt .里面有很多的死的数据.然后,我就是要在这个表中来按条件查询,例如 dt中有个列叫"palte", ...
- SQL中order by;group up;like;关联查询join on的用法
排序order by的用法: 1.order by 字段名1 asc/desc, 字段名2 asc/desc,... 先按照字段名1的升序/降续给表进行排列 然后 按照字段名2的升序/降续给表进行排列 ...
- MyBitis(iBitis)系列随笔之五:多表(一对多关联查询)
MyBitis(iBitis)系列随笔之一:MyBitis入门实例 MyBitis(iBitis)系列随笔之二:类型别名(typeAliases)与表-对象映射(ORM) MyBitis(iBitis ...
- SQL Server中取两个表的交集,并集和差集
在项目中遇到要取两个表差集的情况 假设有两个表tblNZPostCodes, NZPostcode 两个表中存储的都是新西兰的post code信息,字段一致,只是数据上有所差异. 1. Union ...
- vue同一页面中拥有两个表单时,验证问题
问题:如果vue的同一个页面拥有两个表单.验证第一个表单时没有通过就切换到第二个,那么第二个表单会出现验证错误的信息 我们可以通过为两个表单添加ref属性 之后在通过调用resetFields()方法 ...
- 使用SQL语句将数据库中的两个表合并成一张表
select * into 新表名 from (select * from T1 union all select * from T2) 这个语句可以实现将合并的数据追加到一个新表中. 不合并重复数 ...
- SQL中合并两个表的JOIN语句
SQL里有四种JOIN语句用于根据某条件合并两个表: (INNER) JOIN: 交集 LEFT (OUTER) JOIN: 左表数据全包括,右表对应的如果没有就是NULL RIGHT (OUTER) ...
- @ManyToMany 两个表多对多关联
两个表属于多对多关系 如 Teacher <=> Student 表teacher 主键 id 表student 主键id 中间关联表 teacher_student 两个字段 t_id ...
- ofbiz多表外键关联查询
实现一:Screem.xml 中的 section 里,加 <action>, 加 get-related 实现二:在代码中使用 DynamicViewEntity对象,加入addMemb ...
随机推荐
- ASP.NET 截获服务器生成的将要发送到客户端的html的方法
有时候我们需要在将服务器端生成的html发送带客户端之前对这些html进行操作,比如生成静态html加之保存.改变生成的html中的某些内容等等,那么久可以通过如下的方案解决. 我总结了两种方式,个人 ...
- 基于Metronic的Bootstrap开发框架经验总结(13)--页面链接收藏夹功能的实现2(利用Sortable进行拖动排序)
在上篇随笔<基于Metronic的Bootstrap开发框架经验总结(12)--页面链接收藏夹功能的实现>上,我介绍了链接收藏夹功能的实现,以及对收藏记录的排序处理.该篇随笔主要使用功能按 ...
- Mac制作U盘系统(OS X El Capitan)教程
前言部分 重装过Mac OS X系统的人应该都深有体会,通过自带的重新安装 Mac OS X功能恢复系统(开机时按Command+R) 要耗费10几个小时才能完成(请求苹果国外服务器),但如果通过U盘 ...
- Centos下搭建 tomcat https服务器详解(原创)
一 .安装java jdk配置环境变量 1. 卸载原有openjdk yum -y remove java-1.7.0-openjdk* yum -y remove tzdata-java.noarc ...
- jqGrid合并表头
jqGrid是一款常用的制表软件,最近开发刚好用到.记录一下常用功能留着以后查找顺便发扬一下开源精神. 二级表头是一种经常会碰到的需求,很多时候为了方便查找需要在原有的表头上再加一层,区分表格不同列的 ...
- Linux文件管理命令笔记
more\less:翻页命令 more:翻页的形式查看文件内容.该命令可作为管道命令. 翻页过程可使用的键: 空格(space):向下翻页: 回车(Enter):向下翻一行: b:往回翻,只限,但管道 ...
- 窗体作为控件嵌入panel
EyeView frm = new EyeView(); frm.TopLevel = false; frm.Parent = this.panel1; frm.FormBorderStyle = F ...
- jquery实现ajax提交表单信息
最近在思考优化项目,想自己扩展一个jquery自动获取表单中的数据进行ajax提交.本人没有完整性学习jquery,基本上是现学现找,有点困难. 主要是扩展和拼接json转对象 很简单,附上代码: ; ...
- arcgis api for js入门开发系列一arcgis api离线部署
在我的GIS之家QQ群里,很多都是arcgis api for js开发的新手,他们一般都是GIS专业的学生,或者从计算机专业刚刚转向来的giser,他们难免会遇到各种webgis开发的简单问题,由于 ...
- 让ABAP开发者愈加轻松的若干快捷键
引言 ABAP是一种和当代编程语言在许多方面有着相当不同的编程语言.ABAP的某些方面可能会让我们奇怪,为什么它会如此复杂?而它的某些方面又是那么杰出,给予了ABAP开发者们比其它任何语言更多的便利. ...