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;//释放资源

    }