c#基础之DataSet与DataTable

(1)DataSet是数据集,DataTable是数据表,DataSet存储多个DataTable。DataSet和DataTable像是专门存储数据的一个容器,在你查询数据库得到一些结果时可以存在里面。DataReader数据处理速度快,但它是只读的,一旦移到下一行就不能查看上一行的数据,DataSet则可以自由移动指针。DataSet的数据是与数据库断开的。DataSet还可用于多层应用程序中,如果应用程序运行在中间层的业务对象中来访问数据库,则业务对象需将脱机数据结构传递给客户应用程序。

(2)创建函数

DataTable() 不带参数初始化DataTable 类的新实例。 
DataTable(string tableName) 用指定的表名初始化DataTable 类的新实例。 
DataTable(string tableName, string tableNamespace) 用指定的表名和命名空间初始化DataTable 类的新实例。 

(3)SqlDataAdapter是 DataSet和 SQL Server之间的桥接器,用于检索和保存数据。SqlDataAdapter通过对数据源使用适当的Transact-SQL语句映射 Fill(它可更改DataSet中的数据以匹配数据源中的数据)和 Update(它可更改数据源中的数据以匹配 DataSet中的数据)来提供这一桥接。当SqlDataAdapter填充 DataSet时,它为返回的数据创建必需的表和列(如果这些表和列尚不存在)。

如果只需要执行SQL语句或SP,就没必要用到DataAdapter ,直接用SqlCommand的Execute系列方法就可以了。sqlDataadapter的作用是实现Dataset和DB之间的桥梁:比如将对DataSet的修改更新到数据库

由于DataSet是离线处理,所以当在事务处理中要锁定数据库时,不可以使用DataSet。因为当DataSet被填充以后,会自动断开与数据库的连接,此时不可能再对数据库进行锁定。

SqlDataAdapter的UpdateCommand的执行机制是:当调用SqlDataAdapter.Update()时,检查DataSet中的所有行,然后对每一个修改过的Row执行SqlDataAdapter.UpdateCommand ,也就是说如果未修改DataSet中的数据,SqlDataAdapter.UpdateCommand不会执行。

(4)

  

            //(1)构造连接字符串:如果integrated security=true表示可以在不知道数据库用户名和密码的情况下时,依然可以连接数据库,如果integrated security=false,或者不写,表示一定要输入正确的数据库登录名和密码。sspi ,相当于 True,建议用这个代替 True。
            string connSQL = @"data source= ;initial catalog= ;persist security info=True;user id= ;password= ;MultipleActiveResultSets=True";
            

            //(3)打开到数据库的连接 :SqlConnection表示一个到 SQL Server 数据库的打开的连接
            using (SqlConnection conn = new SqlConnection(connSQL))
            {
                //(4)打开连接
                conn.Open();
                //(5)获取数据库表的数据
                string strSql = "SELECT * FROM  表名";

                SqlCommand cmd = new SqlCommand(strSql, conn);

                //(6)示用于填充 System.Data.DataSet 和更新 SQL Server 数据库的一组数据命令和一个数据库连接。 此类不能被继承。
                SqlDataAdapter da = new SqlDataAdapter(cmd); 
                //(7)创建dataset示例
                DataSet ds = new DataSet();
                //填充
                da.Fill(ds, "表名");
                //获取dataset中的多表多行多列。
                foreach (DataTable d in ds.Tables)
                {
                    foreach (DataRow dr in d.Rows)   ///遍历所有的行
                        foreach (DataColumn dc in d.Columns)   //遍历所有的列
                            Console.WriteLine("{0},   {1},   {2}", d.TableName, dc.ColumnName, dr[dc]);   //表名,列名,单元格数据

                  //  Console.WriteLine(d.TableName);
                }

                Console.ReadKey();

            
                conn.Close();




            }

也可以将数据直接放到DataTable中

  // 在使用Fill方式时,可以指定DataTable,而不是DataSet: 
                DataTable tbl = new DataTable("sys_menu");

                da.Fill(tbl);

                foreach (DataRow row in tbl.Rows)
                    foreach (DataColumn col in tbl.Columns) 
                        Console.WriteLine("表名:{0},{1},{2}   ", tbl.TableName, col,row[col]);


                Console.ReadKey();

(5) 

1、在C#中,如果要删除DataTable中的某一行,大约有以下几种办法:

•使用DataTable.Rows.Remove(DataRow),或者DataTable.Rows.RemoveAt(index);可以直接删除行
•datatable.Rows[i].Delete()。Delete()之后需要datatable.AccepteChanges()方法确认完全删除,因为Delete()只是将相应列的状态标志为删除,还可以通过datatable.RejectChanges()回滚,使该行取消删除。
•在删除DataTable中的行的时候,每删除一行,DataTable中所有行的索引都会发生改变。在循环删除DataTable.Row的时候不能使用foreach。使用foreach进行循环的时候,是不允许Table有删除和添加操作的。
•如果是按某列为条件进行删除,则每删完一行,整个Table的index就会立即发生变化,等于Table已经变成了一个新的表。但是索引却已经加1了。于是会造成第一列永远匹配不到。因此,每删除完一行,要跟着判断第一行是否满足删除条件。
•如果要删除DataTable中的多行,应该采用倒序循环DataTable.Rows。因为正序删除时索引会发生变化。程式发生异常,很难预料后果。(不要在循环里使用myDataTable.Rows.RemoveAt(i).因为每删除一行后.i的值会增加,但行数会是减少了.这么做一定会出错.因此要遍历数据,使用Remove方式时,要倒序的遍历)

int count = ds.Tables[0].Rows.Count;
for (int i = count -1; i >=0; i--)

ds.Tables[0].Rows.RemoveAt(i);
}

总结:

delete和remove

•Delete的使用是 datatable.Rows[i].Delete();
•Remove的使用是datatable.Rows.Remove(datatable.Rows[i]);
•这两个的区别是,使用delete后,只是该行被标记为deleted,但是还存在,用Rows.Count来获取行数时,还是删除之前的行数.需要使用datatable.AcceptChanges()方法来提交修改.
而Remove方法则是直接删除.(有时候发现使用ds.Tables[0].Rows[i].Delete();数据行也被直接删除了,原因是在创建datatable时没有执行AcceptChanges这个方法,那么在delete时,不会标记,会直接删除掉。)
•如果在for循环里删除行的话,最好是使用delete方法,不然会出现count变化的情况.循环完后再使用AcceptChanges()方法提交修改,删除掉标记为deleted的行

---注意:(5)是引入的,但是不知道真正的源头来自哪里。

DataTable dt = new DataTable("ta");
            DataRow dr;
            dt.Columns.Add(new DataColumn("主键 ", typeof(Int32)));
            dt.Columns.Add(new DataColumn("字符串值 ", typeof(string)));
            dt.Columns.Add(new DataColumn("日期时间值 ", typeof(DateTime)));
            dt.Columns.Add(new DataColumn("布尔值 ", typeof(bool)));
            for (int i = 1; i <= 2; i++)
            {
                dr = dt.NewRow();
                dr[0] = i;
                dr[1] = "" + i.ToString();
                dr[2] = DateTime.Now;
                dr[3] = (i % 2 != 0) ? true : false;
                dt.Rows.Add(dr);
            }

            foreach (DataRow row in dt.Rows)
                foreach (DataColumn col in dt.Columns)
                    Console.WriteLine("{0},{1},{2}",dt.TableName,col.ColumnName,row[col] );

            

             dt.Rows[1].Delete();

             foreach (DataRow row in dt.Rows)
                 foreach (DataColumn col in dt.Columns)
                     Console.WriteLine("AcceptChanges之前    {0},{1},{2}", dt.TableName, col.ColumnName, row[col]);

             //  提交自上次调用 System.Data.DataTable.AcceptChanges() 以来对该表进行的所有更改。
          dt.AcceptChanges();

排序:

            DataTable dt = new DataTable("ta");
            DataRow dr;
            dt.Columns.Add(new DataColumn("ID", typeof(Int32)));
         
            for (int i = 1; i <= 6; i++)
            {
                dr = dt.NewRow();
                dr[0] = i;
                
                dt.Rows.Add(dr);
            }
             
             
            foreach (DataRow row in dt.Rows)
                foreach (DataColumn col in dt.Columns)
                    Console.WriteLine("{0},{1},{2}",dt.TableName,col.ColumnName,row[col] );

            // 表示用于排序、筛选、搜索、编辑和导航的 System.Data.DataTable 的可绑定数据的自定义视图。
            DataView dv = dt.DefaultView;

            dv.Sort = "ID DESC";

            dt = dv.ToTable();

            foreach (DataRow row in dt.Rows)
                foreach (DataColumn col in dt.Columns)
                    Console.WriteLine("排序后的:  {0},{1},{2}", dt.TableName, col.ColumnName, row[col]);


            Console.ReadKey();
 

ta,ID,1
ta,ID,2
ta,ID,3
ta,ID,4
ta,ID,5
ta,ID,6
排序后的: ta,ID,6
排序后的: ta,ID,5
排序后的: ta,ID,4
排序后的: ta,ID,3
排序后的: ta,ID,2
排序后的: ta,ID,1

原文地址:https://www.cnblogs.com/anjingdian/p/11073802.html