using System; using System.Collections; using System.Data; namespace WindowsFormsApplication4 { public class MegerTable { #region 私有字段 private string LastErrInfo = String.Empty; //最后一次出错信息 #endregion public string GetLastErrInfo() { return LastErrInfo; } /// <summary> /// 将主从表进行左连接操作 /// </summary> /// <param name="mainTable">主表</param> /// <param name="subTable">从表</param> /// <param name="keyFields">关联字段</param> /// <param name="megerFields">子表要合并的字段</param> /// <returns>合并后的表</returns> public DataTable LeftJoinTabel(DataTable mainTable, DataTable subTable, string[] keyFields, string[] megerFields) { if ((keyFields.Length == 0) || (megerFields.Length == 0)) { LastErrInfo = "必须指定关联字段及要合并的字段!"; return null; } foreach (string keyField in keyFields) { if (keyField.Length == 0) { LastErrInfo = "关键字段的列名不允许为空!"; return null; } if (!mainTable.Columns.Contains(keyField)) { LastErrInfo = "主表并没有关键字段[" + keyField + "]!"; return null; } if (!subTable.Columns.Contains(keyField)) { LastErrInfo = "子表并没有关键字段[" + keyField + "]!"; return null; } } foreach (string megerField in megerFields) { if (megerField.Length == 0) { LastErrInfo = "要合并字段的列名不允许为空!"; return null; } if (!subTable.Columns.Contains(megerField)) { LastErrInfo = "子表并没有要合并的字段[" + megerField + "]!"; return null; } } if (mainTable.Rows.Count * subTable.Rows.Count < 5000) { return NestJoin(mainTable, subTable, keyFields, megerFields); } else { if ((megerFields.Length < 5) && (subTable.Rows.Count < 10000)) { return HashJoin(mainTable, subTable, keyFields, megerFields); } else { return IndexJoin(mainTable, subTable, keyFields, megerFields); } } } /// <summary> /// 嵌套循环方式。当主从表都足够小,循环总次数不超过5000时,可免去建立哈希表的开销。 /// </summary> public DataTable NestJoin(DataTable mainTable, DataTable subTable, string[] keyFields, string[] megerFields) { int mainTableSrcCols = mainTable.Columns.Count; //添加主表列 DataColumn newColumn; foreach (string colName in megerFields) { newColumn = new DataColumn(colName); if (mainTable.Columns.Contains(colName)) { newColumn.ColumnName = colName + "$"; } mainTable.Columns.Add(newColumn); } //合并表 bool same; foreach (DataRow mainRow in mainTable.Rows) { foreach (DataRow subRow in subTable.Rows) { //比较当前行的所有关键列值是否一致 same = true; foreach (string keyField in keyFields) { if (mainRow[keyField].ToString() != subRow[keyField].ToString()) { same = false; break; } } //若一致才合并 if (same) { int newColIndex = mainTableSrcCols; foreach (string megerField in megerFields) { mainRow[newColIndex++] = subRow[megerField].ToString(); } } } } return mainTable; } /// <summary> /// 哈希查询方式。当从表比较小,列数少于5且记录数少于1万时,可直接把所有行存入哈希表,就无需再查询从表。 /// </summary> public DataTable HashJoin(DataTable mainTable, DataTable subTable, string[] keyFields, string[] megerFields) { const string SEP = "#%"; //关键字段的列分隔符 int mainTableSrcCols = mainTable.Columns.Count; int subTableSrcCols = subTable.Columns.Count; //将子表放入哈希表 string key; string[] value; Hashtable hashTable = new Hashtable(); foreach (DataRow row in subTable.Rows) { key = row[keyFields[0]].ToString(); for (int i = 1; i < keyFields.Length; i++) { key += SEP + row[keyFields[i]].ToString(); } value = new string[megerFields.Length]; for (int i = 0; i < megerFields.Length; i++) { value[i] = row[megerFields[i]].ToString(); } //哈希表保存主键和实际行内容 hashTable.Add(key, value); } //添加主表列 DataColumn newColumn; foreach (string colName in megerFields) { newColumn = new DataColumn(colName); if (mainTable.Columns.Contains(colName)) { newColumn.ColumnName = colName + "$"; } mainTable.Columns.Add(newColumn); } //合并表 foreach (DataRow row in mainTable.Rows) { key = row[keyFields[0]].ToString(); for (int i = 1; i < keyFields.Length; i++) { key += SEP + row[keyFields[i]].ToString(); } if (hashTable.ContainsKey(key)) { value = hashTable[key] as string[]; for (int i = mainTableSrcCols; i < mainTable.Columns.Count; i++) { row[i] = value[i - mainTableSrcCols]; } } } return mainTable; } /// <summary> /// 哈希索引方式。当从表比较大时,只在哈希表存储索引,找根据索引到从表查询记录,可避免建立过大的哈希表。 /// </summary> public DataTable IndexJoin(DataTable mainTable, DataTable subTable, string[] keyFields, string[] megerFields) { const string SEP = "#%"; //关键字段的列分隔符 int mainTableSrcCols = mainTable.Columns.Count; int subTableSrcCols = subTable.Columns.Count; //将子表索引放入哈希表 int rowIndex = 0; string key; Hashtable hashTable = new Hashtable(); foreach (DataRow row in subTable.Rows) { key = row[keyFields[0]].ToString(); for (int i = 1; i < keyFields.Length; i++) { key += SEP + row[keyFields[i]].ToString(); } //哈希表保存主键和行索引 hashTable.Add(key, rowIndex); rowIndex++; } //添加主表列 DataColumn newColumn; foreach (string colName in megerFields) { newColumn = new DataColumn(colName); if (mainTable.Columns.Contains(colName)) { newColumn.ColumnName = colName + "$"; } mainTable.Columns.Add(newColumn); } //合并表 foreach (DataRow row in mainTable.Rows) { key = row[keyFields[0]].ToString(); for (int i = 1; i < keyFields.Length; i++) { key += SEP + row[keyFields[i]].ToString(); } if (hashTable.ContainsKey(key)) { rowIndex = (int)hashTable[key]; for (int i = mainTableSrcCols; i < mainTable.Columns.Count; i++) { row[i] = subTable.Rows[rowIndex][megerFields[i - mainTableSrcCols].ToString()]; } } } return mainTable; } } }
相关推荐
C#-DataTable操作类(添加自增列、检查是否为数据行、DataTable转换为List、List转换为DataTable,DataTable排序、DataRow转自定义实体)
实现datatable groupby orderby distinct
C#操作EXCEL EXCEL类库 Excel模板处理 将DataTable数据写入Excel文件 C#数据写入EXCEL EXCEL样式管理帮助类库
1 Use VS2010 C# WinForm 2 Use NPOI 2 1 3 net2 3 ExcelToDataTable and DataTableToExcel
ASP.NET C# DataTable与Excel互操作示例.docASP.NET C# DataTable与Excel互操作示例.doc
具体是:用 C# 操作 Excel 表 和 Access数据库,含批量导出、批量导入、批量合并excel、批量打印等功能,范例代码,绝对基础。 共 6 个基础的范例(绝对基础的代码): ① 一键合并多个Excel表; ② 把excel表快速...
C# 维数组转换为DataTable 的三个方法 来了解用C# 操作excel数据转变到dataset 进而到datatable的方式
c# datatable 转实体类,用于操作
c# Excel 操作类,可实现EXCEL的大部分操作,并且可以把数据库查询出的结果datatable直接导到EXCEL里面,注释详细! /// /// 将内存中数据表格插入到Excel指定工作表的指定位置 /// /// 数据表 /// 工作表...
我只好尝试用C#操作EXCEL类,将DATAVIEW的数据写入EXCEL,然后再生成柱状图,花了2天时间找资料,现在可以生成图了,但是生成的图不好看,细节上无法控制。 我把生成图的代码贴下,我再附上XML方式出EXCEL的代码,...
对于这个问题,自己郁闷了四五天的时间,之后终于做出来了,分享一下. 主要是从操作内存中的datatable表,而非直接操作数据库,筛选,去除重复行,sum求和,根据某个字段进行排序等等操作....
用C#操作DataTable生成Excel数据列表,并根据数据列表生成Excel的柱状图或者折线图的报表,内附详细的代码和注释,本人用VS2010写的例子
Excel输出打印模块,将DataTable数据写入Excel文件(自动分页),将DataTable数据写入Excel文件(不分页),将DataTable数据写入Excel文件(自动分页,并指定要合并的列索引) , 将二维数组数据写入Excel文件(自动...
ASP.NET C# DataTable与Excel互操作示例 此页面为html源码 请将后缀改为html或htm再打开
C#的Json操作类,支持数组,DataTable,DataReader等转Json
主要介绍了C#实现Json转DataTable并导出Excel的方法,结合实例形式总结分析了Json转换DataTable,以及DataTable导出Excel相关操作技巧,需要的朋友可以参考下
C#Excel操作类,可以讲Excel与datatable之间转换。支持执行sql语句操作excel。
包括最基本的方法: 打开数据库 关闭数据库 创建SqlCommand命令方法 执行SQL语句方法 将DataReader对象转换成DataTable对象方法
内容概要:本资源介绍了如何从利用Npoi库操作Excel,如相关读取单元格、行,介绍了如何对单元格数据格式进行操作,并分享了如何将Datatable数据导入Mysql数据库,方便项目管理。 阅读建议:此资源以如何读取Excel...