之前通常都是使用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)的更多相关文章

  1. 关于表 datatable的条件查询

    关于表 datatable的条件查询 从数据库中获得一个datatable dt .里面有很多的死的数据.然后,我就是要在这个表中来按条件查询,例如 dt中有个列叫"palte", ...

  2. SQL中order by;group up;like;关联查询join on的用法

    排序order by的用法: 1.order by 字段名1 asc/desc, 字段名2 asc/desc,... 先按照字段名1的升序/降续给表进行排列 然后 按照字段名2的升序/降续给表进行排列 ...

  3. MyBitis(iBitis)系列随笔之五:多表(一对多关联查询)

    MyBitis(iBitis)系列随笔之一:MyBitis入门实例 MyBitis(iBitis)系列随笔之二:类型别名(typeAliases)与表-对象映射(ORM) MyBitis(iBitis ...

  4. SQL Server中取两个表的交集,并集和差集

    在项目中遇到要取两个表差集的情况 假设有两个表tblNZPostCodes, NZPostcode  两个表中存储的都是新西兰的post code信息,字段一致,只是数据上有所差异. 1. Union ...

  5. vue同一页面中拥有两个表单时,验证问题

    问题:如果vue的同一个页面拥有两个表单.验证第一个表单时没有通过就切换到第二个,那么第二个表单会出现验证错误的信息 我们可以通过为两个表单添加ref属性 之后在通过调用resetFields()方法 ...

  6. 使用SQL语句将数据库中的两个表合并成一张表

    select * into 新表名 from (select * from T1 union all select * from T2)  这个语句可以实现将合并的数据追加到一个新表中. 不合并重复数 ...

  7. SQL中合并两个表的JOIN语句

    SQL里有四种JOIN语句用于根据某条件合并两个表: (INNER) JOIN: 交集 LEFT (OUTER) JOIN: 左表数据全包括,右表对应的如果没有就是NULL RIGHT (OUTER) ...

  8. @ManyToMany 两个表多对多关联

    两个表属于多对多关系 如 Teacher <=> Student 表teacher 主键 id 表student 主键id 中间关联表 teacher_student 两个字段 t_id ...

  9. ofbiz多表外键关联查询

    实现一:Screem.xml 中的 section 里,加 <action>, 加 get-related 实现二:在代码中使用 DynamicViewEntity对象,加入addMemb ...

随机推荐

  1. How to implement equals() and hashCode() methods in Java[reproduced]

    Part I:equals() (javadoc) must define an equivalence relation (it must be reflexive, symmetric, and ...

  2. MFC&Halcon之实时视频监控

    上一篇实现了在MFC的窗体内显示图片,本篇介绍如何在MFC窗体内实时显示摄像头的影像. 要实现的功能是点击一个“开始”按钮,可以显示影像,再点击“停止”按钮,可以停止显示. 因为实时显示影像需要在一个 ...

  3. 列表组件抽象(2)-listViewBase说明

    这是我写的关于列表组件的第2篇博客.前面的相关文章有: 1. 列表组件抽象(1)-概述 listViewBase是列表组件所有文件中最核心的一个,它抽象了所有列表的公共逻辑,将来如果有必要添加其它公共 ...

  4. Asp.Net Core 项目实战之权限管理系统(0) 无中生有

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  5. 百度编辑器UEditor与UEditor 公式插件完整Demo

    1.下载UEditor(我的是.net项目) 2.下载UEditor公式插件 3.新建解决方案和项目 4.在浏览器中预览index.html页面 结果: 5.index.html源码 <!DOC ...

  6. python 数据类型---列表使用 之二 (增删改查)

    列表的操作 1.列表的修改 >>> name ['Frank', 'Lee', 2, ['Andy', 'Troy']] >>> name[0] = "F ...

  7. C语言计算2个数的最小公倍数

    #include<stdio.h>int main(){   int a,b,i=1,temp,lcm;   scanf("%d %d",&a,&b); ...

  8. GJM : Unity3D HIAR -【 快速入门 】 一、简介

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  9. struts2中从后台读取数据到<s:select>

    看到网上好多有struts2中从后台读取数据到<s:select>的,但都 不太详细,可能是我自己理解不了吧!所以我自己做了 一个,其中可能 有很多不好的地方,望广大网友指出 结果如图 p ...

  10. ERDAS 2014安装破解及汉化图文教程

    关于ERDAS 2014 的安装破解及其汉化过程: 说明:汉化只是之针对英语能力不能正常满足使用软件的朋友们.如果英语过专八,完全没有必要汉化!在此之前查了好多关于ERDAS汉化的文档,可惜只是简单的 ...