命名空间:sharClass.dataSetHelper
功能:管理内存数据库DataSet
功能详细说明:
数据集辅助类,管理内存数据库DataSet和其数据表DataTable集合。
DataSet是数据集,它可以包含多张数据表(DataTable)。这一点就像是EXCEL工作簿与工作表的关系。
DataSet相当于是内存中的数据库,在数据增加删除查询上拥有速度与方便性上的优势,但是它和正则表达式一样,对它的操作方法属于常学常忘的内容,真到用起来的时候经常必须百度。
这个类可以极大简化DataSet的操作方法,例如:
create开头的方法用于创建表,select开头的方法都是用于查询,update开头的方法用于更新,append开头的方法用于追加数据。
另外这个类可以把表保存为CSV,也可以把表内容序列化保存到磁盘,或者载入。
这个类应用广泛,凡是需要维护批量数据的场合都可以用它,例如保存配置文件,或者维护程序内部的变量集合等等。
netMarketing类库中的动态菜单类和IO表类都是使用它进行内部数据集合的维护。
常用函数列表:
/// 对指定表的全部行做Action,在action中返回-1退出循环 public void RowsForEach(string dataTableName, Func<DataRow, int> act) /// 创建新表,同时指定列名及其数据类型 public void createTable(string tablename, List<datatableStruct> columnNameAndTypeList) /// 创建新表,列名和类型都以逗号分隔的字符表示 public void createTable(string tabName, string colNames, string typeNames, bool isOverrideTab=false) /// 指定表保存到磁盘,逗号分隔符文件,请扩展名改为.csv public string dtWrite(string dataTableName, string path) /// 将dataset序列化到磁盘 public void SerializeToDisk() /// 反序列化,从磁盘载入dataset public void deSerializeFromDisk() /// 清空序列化磁盘文件 public void clearSerializeFile() /// 清空指定表的数据 public void clearDataTable(string tabName) /// 从dataset里面删除数据表 public void delDataTable(string tabName) /// 删除指定行 public void delRow(string dataTableName, int rowIndex) /// 删除多行记录,保留最后指定数量的行 public void delRowsByTotal(string dataTableName, int rowNums) /// 取表的列名及其数据结构 public List<Tuple<string, Type>> getTableColsNameAndDataStruct(string dataTableName) /// 筛选行,按条件 public DataTable select(string dataTableName, string fileterString, string decOrDesc = "") /// 返回指定表的DataView public DataView returnView(string dataTableName) /// 筛选数据,返回行索引 public List<int> selectReturnRowIndex(string dataTableName, string fileterString, string decOrDesc = "") /// 返回变量值。这个函数专门针对两列型表,它返回变量名所在行,第1列的值(0列为变量名列) public object selectVarValue(string dataTableName, string varName) /// 取表前几行记录 public DataTable selectTopData(string dataTableName, int topItems) /// 返回指定列数据,可以指定多列 public DataTable seletColumnData(string dataTableName, string[] columnNames) /// 按表结构列索引,返回该列全部数据 public List<object> selectColumnData(string dataTableName, int colIndex) /// 按内容返回所在行数据,注意搜索内容要求为字符串并且其在表中具有唯一性,否则只返回多个匹配项的第一项 public List<object> selectRowData(string dataTableName, string searchTxt) /// 返回指定一列的非空数据 public List<object> selectColumnDataNotNull(string dataTableName, int colNo) /// 由DataView返回DataTable public DataTable returnDataTable(DataView view) /// 取指定行数据,返回object[] public object[] getRow(string dataTableName, int index) /// 按行索引列字段名的方式取数据 public object getRow(string dataTableName, int index, string colName) /// 在表中增加一条行记录,默认在尾部增加,也可以指定位置插入数据 public void appendRowData(string dataTableName, List<object> data, int dataInsertPos = -1) /// 批量追加行数据,传入行数据为符合逗号分隔符的CSV的格式字符串。 public void addRangeRowData(string dataTableName, List<string> data, int dataInsertPos = -1) /// 增加一条行记录,数据以字符串逗号分隔符提供 public void appendRowData(string dataTableName, string data, int dataInsertPos = -1, bool noRepeatItem = false) /// 更新指定行列的单个单元数据 public void updateDataTable(string dataTableName, int row, int col, object newValue) /// 更新指定行,列名所在的单个单元数据 public void updateDataTable(string dataTableName, int row, string colName, object newValue) /// 更新指定行数据,以字符串serarTXT确定行,因此serarTXT的内容在表中应该是唯一的. public bool updateRowData(string dataTableName, string searchTXT, List<object> updateData) /// 取表在dataSet中的索引号 public int getTableIndex(string tableName) /// 按表在dataSet中的索引号返回DataTable public DataTable returnTableByIndex(int index) /// 由表名返回dataTable对象 public DataTable returnDataTable(string tabName) /// 取dataSet的全部表名字 public List<string> getTableNames() /// 返回dataset名字 public string returnDataSetName() /// 检查用户要创建的表名是否存在 public bool isExistTable(string tabname) /// 行数据在当前活动表中是否存在。数据是CSV格式逗号分隔的,应该与表结构一致。 public bool isExistRow(string dataTableName, string data) /// DataTable分页并取出指定页码的数据 private DataTable getOnePageTable(DataTable dtAll, int pageNo, int pageSize) /// 返回分页后的总页数 public int getTotalPage(int totalCount, int pageSize)
参考例子:
using sharClass;
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 dataSetHelperTest
{
public partial class Form1 : Form
{
dataSetHelper set = new dataSetHelper("set1");
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//两种创建表的方式
set.createTable("tab1", "name,age,workId", "string,int,string");
set.createTable("tab2",
new List<datatableStruct>
{
new datatableStruct{ columnName="name", columnDataType=typeof(string)},
new datatableStruct{ columnName="age", columnDataType=typeof(int)},
new datatableStruct{columnName="workId", columnDataType=typeof(string)}
});
}
private void button2_Click(object sender, EventArgs e)
{
//添加一行数据(方法1)
var name = randomHelper.generatesurname();
var age = randomHelper.GetRandomInt(10, 30+1);
var id = randomHelper.getGuid();
//传入的一行数据为一个List<Object>列表
set.appendRowData("tab1", new List<Object> { name, age, id });
name = randomHelper.generatesurname();
age = randomHelper.GetRandomInt(10, 30 + 1);
id = randomHelper.getGuid();
//传入的一行数据为一个CSV格式的逗号分隔串
set.appendRowData("tab2", new List<string>() { name, age.ToString(), id }.createCSVRow());
dgv1.DataSource = null;
dgv2.DataSource = null;
dgv1.DataSource = set.returnDataTable("tab1");
dgv2.DataSource = set.returnDataTable("tab2");
}
private void button3_Click(object sender, EventArgs e)
{
//添加一行数据(方法2,由CSV文件批量增加)
var list1 = new List<string>();
for (int i = 0; i < 10; i++)
{
var name = randomHelper.generatesurname();
var age = randomHelper.GetRandomInt(10, 30 + 1);
var id = randomHelper.getGuid();
list1.Add(CSVHelper.createCSVRow(new List<string>() { name, age.ToString(), id }));
}
set.addRangeRowData("tab1", list1);
list1.Clear();
for (int i = 0; i < 10; i++)
{
var name = randomHelper.generatesurname();
var age = randomHelper.GetRandomInt(10, 30 + 1);
var id = randomHelper.getGuid();
list1.Add(CSVHelper.createCSVRow(new List<string>() { name, age.ToString(), id }));
}
set.addRangeRowData("tab2", list1);
dgv1.DataSource = null;
dgv2.DataSource = null;
dgv1.DataSource = set.returnDataTable("tab1");
dgv2.DataSource = set.returnDataTable("tab2");
}
private void button4_Click(object sender, EventArgs e)
{
//清空数据表
set.clearDataTable("tab1");
set.clearDataTable("tab2");
dgv1.DataSource = null;
dgv2.DataSource = null;
dgv1.DataSource = set.returnDataTable("tab1");
dgv2.DataSource = set.returnDataTable("tab2");
}
private void button5_Click(object sender, EventArgs e)
{
//取列名和数据结构
var list1=set.getTableColsNameAndDataStruct("tab1");
foreach(var m in list1)
{
richTextBox1.AppendText($"列名:{m.Item1},数据类型:{m.Item2}\r\n");
}
}
private void button6_Click(object sender, EventArgs e)
{
//按列搜索
try
{
var res = set.select("tab1", "name like 's%'");
dgv3.DataSource = null;
dgv3.DataSource = res;
res = set.select("tab2", "age >= 10");
dgv4.DataSource = null;
dgv4.DataSource = res;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button7_Click(object sender, EventArgs e)
{
//取指定列的数据
//按列名取
var res=set.seletColumnData("tab1", new string[] { "name" });
dgv3.DataSource = null;
dgv3.DataSource = res;
//按列索引取
var res1 = set.selectColumnData("tab2", 0);
var sb1 = new StringBuilder();
foreach (var m in res1)
{
sb1.Append(m.ToString());
sb1.Append(",");
}
richTextBox1.AppendText(sb1.ToString());
}
private void button8_Click(object sender, EventArgs e)
{
//按内容返回行
set.appendRowData("tab1", new List<Object> { "勇哥", 100, "id12345" });
set.appendRowData("tab1", new List<Object> { "勇哥", 100, "id123456" });
var res1=set.selectRowData("tab1", "id123456");
var sb1 = new StringBuilder();
foreach (var m in res1)
{
sb1.Append(m.ToString());
sb1.Append(",");
}
richTextBox1.AppendText(sb1.ToString());
}
private void button9_Click(object sender, EventArgs e)
{
//取指定行数据
set.appendRowData("tab1", new List<Object> { "勇哥1", 100, "id12345" });
set.appendRowData("tab1", new List<Object> { "勇哥2", 100, "id123456" });
var index = set.selectReturnRowIndex("tab1", "name = '勇哥1'")[0];
var res=set.getRow("tab1",index);
var sb1 = new StringBuilder();
foreach (var m in res)
{
sb1.Append(m.ToString());
sb1.Append(",");
}
richTextBox1.AppendText(sb1.ToString());
MessageBox.Show("按行索引列字段名的方式取数据: " + set.getRow("tab1", index, "workId").ToString());
}
private void button10_Click(object sender, EventArgs e)
{
//更新指定行列的数据
set.appendRowData("tab1", new List<Object> { "勇哥1", 100, "id12345" });
set.appendRowData("tab1", new List<Object> { "勇哥2", 100, "id123456" });
set.updateDataTable("tab1", 0, 0, "勇哥威武");
dgv3.DataSource = null;
dgv3.DataSource = set.returnDataTable("tab1");
}
private void button11_Click(object sender, EventArgs e)
{
//更新一行的数据
set.appendRowData("tab1", new List<Object> { "勇哥1", 100, "id12345" });
set.appendRowData("tab1", new List<Object> { "勇哥2", 100, "id123456" });
set.updateRowData("tab1", "勇哥1", new List<object>() { "勇哥威武", 110, "id9988" });
dgv3.DataSource = null;
dgv3.DataSource = set.returnDataTable("tab1");
}
private void button12_Click(object sender, EventArgs e)
{
//保存为CSV
set.dtWrite("tab1", $"d:\\{set.getTableNames()[0]}.csv");
}
private void button13_Click(object sender, EventArgs e)
{
//二进制写入
set.SerializeToDisk();
}
private void button14_Click(object sender, EventArgs e)
{
//二进制读取
set.deSerializeFromDisk();
dgv1.DataSource = null;
dgv2.DataSource = null;
dgv1.DataSource = set.returnDataTable("tab1");
dgv2.DataSource = set.returnDataTable("tab2");
}
}
}
2019/3/31勇哥注:
关于多线程下dataSetHelper绑定到dataGridView控件出现的错误,解决办法见下面的贴子:

解决netMarketing类库dataSetHelper类在多线程下的使用问题
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!


少有人走的路


















