【淘宝ERP-资料收集】关于Datatable的一些用法

C# DataTable.Select() 筛选数据 返回新DataRow[]

有时候我们需要对数据表进行筛选,微软为我们封装了一个公共方法,DataTable.Select(),其用法如下:

Select()

Select(string filterExpression)

Select(string filterExpression, string sort)

Select(string filterExpression,string sort, DataViewRowState record States)

1)  Select()——获取所有 System.Data.DataRow 对象的数组;

2)  Select(string filterExpression)——按照主键顺序(如果没有主键,则按照添加顺序)获取与筛选条件相匹配的所有 System.Data.DataRow 对象的数组;

3)  Select(string filterExpression, string sort)——获取按照指定的排序顺序且与筛选条件相匹配的所有System.Data.DataRow 对象的数组;

4)  Select(string filterExpression, string sort, DataViewRowState recordStates)——获取与排序顺序中的筛选器以及指定的状态相匹配的所有。

举例说明:

有一个用户表,名称为 dtUsers,有id、姓名name、性别sex、年龄age

1.筛选所有的用户  

         DataRow[] drs1 =dtUsers.Select();

2.筛选所有性别为男的用户

         DataRow[] drs2 =dtUsers.Select("sex = '男' ");

3.筛选所有性别为男且年龄在18岁以上的用户

         DataRow[] drs3 =dtUsers.Select("sex = '男' and age >= 18");

4.筛选所有性别为男或者年龄在18岁以上的用户

         DataRow[] drs4 =dtUsers.Select("sex = '男' or age >= 18");

5.筛选所有姓“夏”的用户

         DataRow[] drs5 =dtUsers.Select("name like '夏%'");

6.筛选所有18岁以上的用户且按从大到小的顺序排序

         DataRow[] drs5 =dtUsers.Select("age >=18","age desc");

7.上面最后一种用法没试过,有机会再列举出来。


注意事项

1.上面的Select操作是不区分大小写的(表字段不敏感,如pl-sql语法),如果需要区分大小写,需要将DataTable的caseSensitive属性设为true,例如上表的

dtUsers.CaseSensitive = true;//区分大小写
 

C#中DataRow的初始化

那么如何初始化这一个DataRow呢?我们知道,DataRow是DataTable的组件,而且在MSDN上可以看到DataRow的构造函数是protected类型的,它只能在内部进行构造,单独的实例化,DataRow row = new DataRow ()是不允许的。那么我们要使用DataRow就有以下两种方法进行实例化。

1、已知已存在的一个DataTable的对象table,当然这个对象的结构都已经有了,如下

DataRow row=table.NewRow();
这样便实例化了一个和已知的table一样的结构的一个DataRow 对象,可以对列进行赋值操作。

2、没有已知的DataTable,但是又想按自己写的结构保存,那么,就需要先实例化一个和你的需求一样的DataTable,然后,如1进行实例化。

   static DataTable dt = null;
        private static DataTable Dt
        {
            get 
            {
                if (dt == null)
                {
                    dt = new DataTable();
 
                    dt.Columns.Add(列名1);
 
                    dt.Columns.Add(列名2);
 
                    dt.Columns.Add(列名3);
                }
                return dt;
            }
        }
实例化DataRow,

DataRow row=Dt.NewRow();
那么如果这个row在别的地方被引用,就可以取值

object value = row[列名1]
这样我们就可以在程序中保存一些数据,而不用再写一个Model类来保存了,避免在其他地方引用不方便。
 

如何给DataTable、DataRow 手动赋值

DataTable MyDataTable = new DataTable();

            MyDataTable.Columns.Add(new DataColumn("学生编号", typeof(string)));
            MyDataTable.Columns.Add(new DataColumn("姓名", typeof(string)));
            MyDataTable.Columns.Add(new DataColumn("学校", typeof(string)));
            MyDataTable.Columns.Add(new DataColumn("联系电话", typeof(string)));
            MyDataTable.Columns.Add(new DataColumn("家庭住址", typeof(string)));

            DataRow dr;
            for (int i = 0; i <= 10; i++)
            {
                dr = MyDataTable.NewRow();
                dr["学生编号"] = Guid.NewGuid().ToString();
                dr["姓名"] = "222";
                dr["学校"] = "444";
                dr["联系电话"] = "555";
                dr["家庭住址"] = "666";

                MyDataTable.Rows.Add(dr);
            }

DataRow 类

DataRow 和 DataColumn 对象是 DataTable 的主要组件。使用 DataRow 对象及其属性和方法检索、评估、插入、删除和更新DataTable 中的值。DataRowCollection 表示 DataTable 中的实际 DataRow 对象,DataColumnCollection 中包含用于描述DataTable 的架构的 DataColumn 对象。使用重载的 Item 属性返回或设置 DataColumn 的值。

使用 HasVersion 和 IsNull 属性确定特定行值的状态,使用 RowState 属性确定行相对于它的父级 DataTable 的状态。

若要创建新的 DataRow,请使用 DataTable 对象的 NewRow 方法。创建新的 DataRow 之后,请使用 Add 方法将新的 DataRow添加到 DataRowCollection 中。最后,调用 DataTable 对象的 AcceptChanges 方法以确认是否已添加。有关将数据添加到DataTable 中的更多信息,请参见 将数据添加到表中。

您可通过调用 DataRowCollection 的 Remove 方法或调用 DataRow 对象的 Delete 方法,从 DataRowCollection 中删除DataRow。Remove 方法将行从集合中移除。与此相反,Delete 标记要移除的 DataRow。在调用 AcceptChanges 方法时发生实际移除。通过调用 Delete,您可在实际删除行之前以编程方式检查哪些行被标记为移除。有关更多信息,请参见 从表中删除行。

下面的示例通过调用 DataTable 对象的 NewRow 方法创建新的 DataRow

        private void CreateNewDataRow()
        {
            // Use the MakeTable function below to create a new table.
            DataTable table;
            table = MakeNamesTable();

            // Once a table has been created, use the 
            // NewRow to create a DataRow.
            DataRow row;
            row = table.NewRow();

            // Then add the new row to the collection.
            row["fName"] = "John";
            row["lName"] = "Smith";
            table.Rows.Add(row);

            foreach (DataColumn column in table.Columns)
                Console.WriteLine(column.ColumnName);
            dataGrid1.DataSource = table;
        }

        private DataTable MakeNamesTable()
        {
            // Create a new DataTable titled 'Names.'
            DataTable namesTable = new DataTable("Names");

            // Add three column objects to the table.
            DataColumn idColumn = new DataColumn();
            idColumn.DataType = System.Type.GetType("System.Int32");
            idColumn.ColumnName = "id";
            idColumn.AutoIncrement = true;
            namesTable.Columns.Add(idColumn);

            DataColumn fNameColumn = new DataColumn();
            fNameColumn.DataType = System.Type.GetType("System.String");
            fNameColumn.ColumnName = "Fname";
            fNameColumn.DefaultValue = "Fname";
            namesTable.Columns.Add(fNameColumn);

            DataColumn lNameColumn = new DataColumn();
            lNameColumn.DataType = System.Type.GetType("System.String");
            lNameColumn.ColumnName = "LName";
            namesTable.Columns.Add(lNameColumn);

            // Create an array for DataColumn objects.
            DataColumn[] keys = new DataColumn[1];
            keys[0] = idColumn;
            namesTable.PrimaryKey = keys;

            // Return the new DataTable.
            return namesTable;
        }

关于Datatable的一些用法

C#动态操作DataTable(新增行、列、查询行、列等)  

方法一:动态创建一个DataTable ,并为其添加数据

public void CreateTable()
        {
            //创建表
            DataTable dt = new DataTable();

            //1、添加列
            dt.Columns.Add("Name", typeof(string)); //数据类型为 文本

            //2、通过列架构添加列
            DataColumn age = new DataColumn("Age", typeof(Int32));   //数据类型为 整形
            DataColumn Time = new DataColumn("Time", typeof(DateTime)); //数据类型为 时间
            dt.Columns.Add(age);
            dt.Columns.Add(Time);

            //1、添加空行
            DataRow dr1 = dt.NewRow();
            dt.Rows.Add(dr1);

            //2、添加空行
            dt.Rows.Add();

            //3、添加数据行
            DataRow dr2 = dt.NewRow();
            dr2[0] = "张三"; //通过索引赋值
            dr2[1] = 23;
            dr2["Time"] = DateTime.Now;//通过名称赋值
            dt.Rows.Add(dr2);

            //4、通过行框架添加
            dt.Rows.Add("李四", 25, DateTime.Now);//Add你们参数的数据顺序要和dt中的列顺对应

        }

方法二:为已有DateTable添加一新列,其值可设为默认值,也可设这列不可为空。

        public void CreateTable(DataTable vTable)
        {
            //为已有DataTable添加一新列
            DataColumn dc1 = new DataColumn("Tol", typeof(string));
            vTable.Columns.Add(dc1);

            //添加一新列,其值为默认值
            DataColumn dc2 = new DataColumn("Sex", typeof(string));
            dc2.DefaultValue = "男";
            dc2.AllowDBNull = false;//这在初床表的时候,其作用,在为已有表新增列的时候,不起作用
            vTable.Columns.Add(dc2);
        }

方法三:筛选DataTable中的数据,使用 Select()方法,把赛选结果可以保存到 DataRow[] drArr; 数据里面,也可以另存为一个新DataTable

            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(),上面的操作可以改成这样:

            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赋值给新的DataTable,怎么赋值呢?你可能会想到: 
            DataTable dtNew1 = dt.Clone();
            for (int i = 0; i < drArr.Length; i++)
            {
                dtNew1.Rows.Add(drArr[i]);
            }
            
            //但这样程序就会出错,说该DataRow是属于其他DataTable的,那要怎么做呢?很简单,这样就可以解决了: 
            DataTable dtNew2 = dt.Clone();
            for (int i = 0; i < drArr.Length; i++)
            {
                dtNew2.ImportRow(drArr[i]);//ImportRow 是复制
            }
        }
 

方法四:对DataTable筛选指定字段,并保存为新表

        public void SelectColumnDataTable(DataTable dt)
        {
            //对DataTable筛选指定字段,并保存为新表
            DataTable dtNew = dt.DefaultView.ToTable(false, new string[] { "列名", "列名", "列名" });//这些列名,确保dt中存在,否则会报错误
        }

方法五:对DataTable进行排序设置(sort)

        public void SortDataTable(DataTable dt)
        {
            dt.DefaultView.Sort = "id desc";//重新设置排序
            DataTable dtNew = dt.DefaultView.ToTable(); //保存在一张新表中
        }
 

方法六:对DataTable去除重复行
   1 数据库直接去除重复
   select distinct * from 表名
    去除了重复行distinct

2 对 DataTable直接进行操作
     DataTable dt=db.GetDt("select * from 表名"); //获得datatable
    DataView dv = new DataView(dt); //虚拟视图吧,我这么认为
    DataTable dt2 = dv.ToTable(true, "name,age,hobby");
    这个时候 dt2就是去除了重复的行了
    其中
    dv.ToTable(true, "name,age,hobby");
    第一个参数,true 去除重复,false 不去除
    第二个参数, 看意思能明白,你需要显示的字段,我这里显示"name,age,hobby"
方法七:DataTable 修改列名 删除列 增加列 调整列顺序

DataTable myDt =dt;  
    //删除列  
    myDt.Columns.Remove("minArea");  
    myDt.Columns.Remove("maxArea");  
      
    //调整列顺序 ,列排序从0开始  
    myDt.Columns["num"].SetOrdinal(1);  
      
    //修改列标题名称  
    dt.Columns["num"].ColumnName = "搜索量";  
    dt.Columns["rate"].ColumnName = "百分比";  
    
    DataColumn priceColumn = new DataColumn();
        //该列的数据类型
        priceColumn.DataType = System.Type.GetType("System.String");
        //该列得名称
        priceColumn.ColumnName = "price";
        //该列得默认值
        priceColumn.DefaultValue ="test";
        
    dt.Columns.Add(priceColumn);
 

DataTable添加列和行的三种方法

 #region 方法一: 
            DataTable tblDatas = new DataTable("Datas");
            DataColumn dc = null;
            dc = tblDatas.Columns.Add("ID", Type.GetType("System.Int32"));
            dc.AutoIncrement = true;//自动增加 
            dc.AutoIncrementSeed = 1;//起始为1 
            dc.AutoIncrementStep = 1;//步长为1 
            dc.AllowDBNull = false;
            dc = tblDatas.Columns.Add("Product", Type.GetType("System.String"));
            dc = tblDatas.Columns.Add("Version", Type.GetType("System.String"));
            dc = tblDatas.Columns.Add("Description", Type.GetType("System.String"));
            DataRow newRow;
            newRow = tblDatas.NewRow();
            newRow["Product"] = "这个地方是单元格的值";
            newRow["Version"] = "2.0";
            newRow["Description"] = "这个地方是单元格的值";
            tblDatas.Rows.Add(newRow);
            newRow = tblDatas.NewRow();
            newRow["Product"] = "这个地方是单元格的值";
            newRow["Version"] = "3.0";
            newRow["Description"] = "这个地方是单元格的值";
            tblDatas.Rows.Add(newRow);
            #endregion
            #region 方法二: 
            DataTable tblDatas = new DataTable("Datas");
            tblDatas.Columns.Add("ID", Type.GetType("System.Int32"));
            tblDatas.Columns[0].AutoIncrement = true;
            tblDatas.Columns[0].AutoIncrementSeed = 1;
            tblDatas.Columns[0].AutoIncrementStep = 1;
            tblDatas.Columns.Add("Product", Type.GetType("System.String"));
            tblDatas.Columns.Add("Version", Type.GetType("System.String"));
            tblDatas.Columns.Add("Description", Type.GetType("System.String"));
            tblDatas.Rows.Add(newobject[] { null, "a", "b", "c"});
            tblDatas.Rows.Add(newobject[] { null, "a", "b", "c"});
            tblDatas.Rows.Add(newobject[] { null, "a", "b", "c"});
            tblDatas.Rows.Add(newobject[] { null, "a", "b", "c"});
            tblDatas.Rows.Add(newobject[] { null, "a", "b", "c"});
            #endregion
#region 方法三: 
            DataTable table = new DataTable();
            //创建table的第一列 
            DataColumn priceColumn = new DataColumn();
            priceColumn.DataType = System.Type.GetType("System.Decimal");//该列的数据类型 
            priceColumn.ColumnName = "price";//该列得名称 
            priceColumn.DefaultValue = 50;//该列得默认值 
                                          // 创建table的第二列 
            DataColumn taxColumn = new DataColumn();
            taxColumn.DataType = System.Type.GetType("System.Decimal");
            taxColumn.ColumnName = "tax";//列名 
            taxColumn.Expression = "price * 0.0862";//设置该列得表达式,用于计算列中的值或创建聚合列 
                                                    // 创建table的第三列 
            DataColumn totalColumn = new DataColumn();
            totalColumn.DataType = System.Type.GetType("System.Decimal");
            totalColumn.ColumnName = "total";
            totalColumn.Expression = "price + tax";//该列的表达式,是第一列和第二列值得和 
                                                   // 将所有的列添加到table上 
            table.Columns.Add(priceColumn);
            table.Columns.Add(taxColumn);
            table.Columns.Add(totalColumn);
            //创建一行 
            DataRow row = table.NewRow();
            table.Rows.Add(row);//将此行添加到table中 
                                //将table放在视图中 
            DataView view = new DataView(table);
            //绑定到DataGrid 
            dg.DataSource = view;
            dg.DataBind();
            #endregion

将DataTable一行放入另一个DataTable中

【概述】从一个DataTable中取一行放到另一个DataTable里报错: 该行已经属于另一个表

第1种方法:

DataTable dt = new DataTable();
dt = ds.Tables["All"].Clone();//克隆All的结构传递给dt
DataRow[] dr = this.dataSet31.Tables["Product"].Select("bc=1"); //通过条件得到符合条件的行

for(int i=0;i<dr.Length;i++)
{
    //将数组元素加入表...
    dt.Rows.Add(dr[i]);//出错提示为:该行已经属于另一个表
}
    // 修改后
    DataTable dt = new DataTable();
    dt = ds.Tables["All"].Clone();//克隆All的结构传递给dt
    DataRow[] dr = this.dataSet31.Tables["Product"].Select("bc=1"); //通过条件得到符合条件的行
for(int i=0;i<dr.Length;i++)
{
    //将数组元素加入表...
    dt.Rows.Add(dr[i].ItemArray);
}

第2种方法:

DataTable dt1 = new DataTable();
DataTable calcdt = new DataTable();
// dt1只是获取表结构,无数据;
// calcdt 有表结构,有数据
// 原方法
foreach (DataRow dr in calcdt.Rows)
{
    dt1.Rows.Add(dr);
}

    // 改进后的方法
    DataRow drcalc;
foreach (DataRow dr in calcdt.Rows)
{
    drcalc = dt1.NewRow();
    drcalc.ItemArray = dr.ItemArray;
    dt1.Rows.Add(drcalc);
}

猜你喜欢

转载自blog.csdn.net/zgscwxd/article/details/86672865