DataTable相关操作
用法一:动态创建一个DataTable ,并为其添加数据
public void CreateTable()
{
//创建表
DataTable dt = new DataTable();
//1、添加列
dt.Columns.Add("empName", typeof(string)); //数据类型为 文本
//2、通过列架构添加列
DataColumn age = new DataColumn("Age", typeof(Int32)); //数据类型为 整形
DataColumn datetime = new DataColumn("theDateTime", typeof(DateTime)); //数据类型为 时间
dt.Columns.Add(age);
dt.Columns.Add(datetime);
//1、添加空行
DataRow newRow = dt.NewRow();
dt.Rows.Add(newRow);
//2、添加空行
dt.Rows.Add();
//3、添加数据行
DataRow dr2 = dt.NewRow();
dr2[0] = "张三"; //通过索引赋值
dr2[1] = 28;
dr2["theDateTime"] = DateTime.Now;//通过名称赋值
dt.Rows.Add(dr2);
//4、通过行框架添加
dt.Rows.Add("李四",26,DateTime.Now);//参数的数据顺序要和dt中的列顺序对应
}
用法二:为已有DataTable添加一新列,其值可设为默认值,也可设这列不可为空。
public void CreateTable(DataTable dtTable)
{
//为已有DataTable添加一新列
DataColumn dc1 = new DataColumn("EmpName", typeof(string));
dtTable.Columns.Add(dc1);
//添加一新列,其值为默认值
DataColumn dc2 = new DataColumn("Sex", typeof(string));
dc2.DefaultValue = "男";
dc2.AllowDBNull = false;//这在初始表的时候,有作用;为已有表新增列的时候,不起作用
dtTable.Columns.Add(dc2);
}
用法三:筛选DataTable中的数据
public void SelectRowDataTable()
{
DataTable dt = new DataTable();//假设dt是由"SELECT C1,C2,C3 FROM T1"查询出来的结果
for (int i = 0; i < dt.Rows.Count; i++)
{
if (dt.Rows[i]["C1"].ToString() == "abc")//查询条件
{
//进行操作
}
}
//但这种做法用一两次还好说,用多了就累了。那有没有更好的方法呢?就是dt.Select(),上面的操作可以改成这样:
Select筛选数据的用法与SQL相似:
支持:'=','<>','>','<','and','or','in','like';
不支持:'between','!='
DataRow[] drArr = dt.Select("C1='abc'");//查询(如果Select内无条件,就是查询所有的数据)
//还可以这样操作:
DataRow[] drArr1 = dt.Select("C1 LIKE 'abc%'");//模糊查询(如果的多条件筛选,可以加 and 或 or )
DataRow[] drArr2 = dt.Select("'abc' LIKE C1 + '%'", "C2 DESC");//另一种模糊查询的方法
DataRow[] drArr3 = dt.Select("C1='abc'", "C2 DESC");//排序
DataRow[] drArr4 = dt.Select("C1 > 1 and C1 < 8");//筛选出一段范围内值(注:Select中没有between 用法,所以下面方法不可使用,dt.Select("C1 between 1 and 8"))
//问题来了,筛选出来的记录,想要修改后,更新到原来DataTable中,怎么弄呢?你可能会想到for循环,找到对应行,修改值。这是种方法,有没有更简单的呢?答案是肯定的
//DataTable.Select()方法筛选出来想要的记录,直接修改这些记录,是会自动更新到原DataTable中的。
DataRow[] drArr = dt.Select("C1='abc'");//查询出C1列为abc的记录,假如查出来是一行记录
drArr[0]["C1"]="aaa";drArr[0]["C2"]="bbb";drArr[0]["C3"]="ccc";//通过修改drArr中的值,原表dt中值会自动更新。
//问题又来了,如果要把DataRow赋值给新的DataTable,怎么赋值呢?你可能会想到:
DataTable dtNew1 = dt.Clone();
for (int i = 0; i < drArr1.Length; i++)
{
dtNew1.ImportRow(drArr1[i]);//ImportRow 是复制
}
//上面方法在数据量少的情况,处理还好,如果数据量一大就会很慢,有没有更快的方法呢,能一次性将查询出来的DataRow数组drArr1一次赋值给新的DataTable呢?肯定是有的,方法如下:
DataTable dtNew2 =null;
dtNew2=DataRow_DataTable(drArr1,"Table1");//调用转换方法,将DataRow数组一次性生成DataTable
}
/// <summary>
/// 将DataRow数组一次性转成DataTable
/// </summary>
/// <param name="drArray"></param>
/// <param name="sTableName"></param>
/// <returns></returns>
public DataTable DataRow_DataTable(DataRow[] drArray,string sTableName)
{
DataSet tempDs = null;
DataTable tempTable = new DataTable();
if (drArray.Length > 0)
{
tempDs = new DataSet();
tempDs.Merge(drArray);//利用数据集添加DataRow数组到表(DataTable的Merge的方法是没有这个功能的)
tempTable = tempDs.Tables[0];
tempTable.TableName = sTableName;//设置表名
try
{
tempTable.PrimaryKey = new DataColumn[] { tempTable.Columns["workcardid"] };//设定主键以加速查找Select速度
}
catch
{ }
}
return tempTable;//返回此表
}
用法四:对DataTable筛选指定字段,并保存为新表
public void SelectColumnDataTable(DataTable dt)
{
//对DataTable筛选指定字段,并保存为新表
DataTable dtNew = dt.DefaultView.ToTable(false, new string[] { "列名", "列名", "列名" });//这些列名,确保dt中存在,否则会报错误
//筛选DataTable指定字段,并将该字段中唯一值保存到新表
DataTable dtNew = dt.DefaultView.ToTable(true, new string[] { "待筛选的列名" });
}
用法五:对DataTable进行排序设置(sort)
public void SortDataTable(DataTable dt)
{
dt.DefaultView.Sort = "id desc";//重新设置排序
DataTable dtNew = dt.DefaultView.ToTable(); //保存在一张新表中
}
用法六:通过设置DataTable.DefaultView.RowFilter条件,筛选DataGridView中指定条件的数据
private void txtFilterValue_TextChanged(object sender, EventArgs e)
{
//根据文本框输入值,进行筛选数据
try
{
DataView dv = null;
string displayMember = "";
DataTable dtDataSource = DataGridView1.DataSource as DataTable;
if (dtDataSource != null && dtDataSource.Columns.Count >= 2)//DataTable中有两列,列名是ID、ItemName
{
dv = dtDataSource.DefaultView;
displayMember = dtDataSource.Columns[1].ColumnName;
dv.RowFilter = displayMember + " like '%" + txtFilterValue.Text.Trim() + "%'";//根据文本框输入值,进行筛选数据,执行完该语句,DataGridView1中数据只剩下筛选的数据
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
用法七:DataTable添加主键
/// <summary>
/// DataTable中添加多列主键,并显示主键列
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnPrimaryKey_Click(object sender, EventArgs e)
{
string sqlGetEmpInfo = "select rtrim(ltrim(empGeneral.empid)) as empID, empGeneral.empcname as empcname, Departments.deptname as deptname, Positions.posname as posname, "
+ " empcards.workcardid as workcardid from Departments, Positions, empcards, empGeneral "
+ " where (empGeneral.empID = empcards.empID And empGeneral.deptID = Departments.deptID And empGeneral.posID = Positions.posID) And (empGeneral.leaveDate is null or empGeneral.leaveDate ='') and empcards.statusFlag='1' "
+ " order by empID";
DataTable dtKey = null;
dbo.CommandString = sqlGetEmpInfo;
dtKey = dbo.GetDataTable();
try
{
//添加单列主键,如果workcardID有重复值,无法添加主键
//dtKey.PrimaryKey = new DataColumn[] { dtKey.Columns["workcardID"]};
//添加多列主键,只有当workcardID和empID同时重复才无法添加主键,当两人共有一卡号时,是可以添加主键的
dtKey.PrimaryKey = new DataColumn[] { dtKey.Columns["workcardID"], dtKey.Columns["empID"] };
}
catch (Exception er)
{
}
//提取主键,并显示
DataColumn[] dc = dtKey.PrimaryKey;
string sKeyColumnName = "";
for (int i = 0; i < dc.Length; i++)
{
sKeyColumnName += dc[i].ColumnName+"\r\n";
}
MessageBox.Show("包含主键的列名:\r\n"+sKeyColumnName);
string dt1, dt2;
string strEmpID = "";
dt1 = DateTime.Now.ToString("HH:mm:ss.ffff");
DataRow[] drArray=dtKey.Select("workcardid like '%1'","empID DESC");//提前卡号workcardid最后一位是1的名单,且按照工号empID降序
dt2 = DateTime.Now.ToString("HH:mm:ss.ffff");
foreach(DataRow dr in drArray)
{
strEmpID+=dr["empID"]+"\r\n";
}
MessageBox.Show(dt1 + "\r\n" + dt2+"\r\n"+strEmpID);
//MessageBox.Show((dt2 - dt1).TotalMilliseconds.ToString());
}
用法八:DataRow数组转DataTable
public DataTable DataRow_DataTable(DataRow[] drArray,string sTableName)
{
DataSet tempDs = null;
DataTable tempTable = new DataTable();
if (drArray.Length > 0)
{
tempDs = new DataSet();
tempDs.Merge(drArray);//利用数据集合并行集到表
tempTable = tempDs.Tables[0];
tempTable.TableName = sTableName;
try
{
tempTable.PrimaryKey = new DataColumn[] { tempTable.Columns["workcardid"] };//设定PK以加速Find速度
}
catch
{ }
}
else
{
tempTable = dtName.Clone();//克隆生成DataRow的DataTable结构
tempTable.TableName = sTableName;
}
return tempTable;//返回此表
}
DataTable dtName = null;
DataSet dsEmpDetaile = new DataSet();
//测试
private void btnClick_Click(object sender, EventArgs e)
{
DataSet dsEmpInfo = new DataSet();
string sqlGetEmpInfo = "select rtrim(ltrim(empGeneral.empid)) as empID, empGeneral.empcname as empcname, Departments.deptname as deptname, Positions.posname as posname, "
+ " empcards.workcardid as workcardid from Departments, Positions, empcards, empGeneral "
+ " where (empGeneral.empID = empcards.empID And empGeneral.deptID = Departments.deptID And empGeneral.posID = Positions.posID) And (empGeneral.leaveDate is null or empGeneral.leaveDate ='') and empcards.statusFlag='1' "
+ " order by empID";
dtName = new DataTable();
dbo.CommandString = sqlGetEmpInfo;
dtName = dbo.GetDataTable();
dsEmpDetaile = new DataSet();
DataTable dtTest = DataRow_DataTable(dtName.Select("workcardID like '%1' or workcardID like '%2'", "empID ASC"), "T12");//查询出卡号最后一位是1或2的所有记录,并将记录按照empID升序
DataTable dtTest2 = DataRow_DataTable(dtName.Select("workcardID like '%3' or workcardID like '%4'", "empID ASC"), "T34");
dsEmpInfo.Tables.Add(dtTest.Copy());
dsEmpInfo.Tables.Add(dtTest2.Copy());
dsEmpDetaile = dsEmpInfo;
dtName =null;//释放资源
}