zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    2021年中国DevOps现状调查报告发布!
    带你看清梦饷集团如何成为上海在线新经济四小龙
    AI论文解读丨融合视觉、语义、关系多模态信息的文档版面分析架构VSR
    云图说 | 华为云医疗智能体,智联大健康,AI药物研发
    带你走进“华为链”
    初学者入门知识图谱必看的能力:推理
    带你探索CPU调度的奥秘
    鸿蒙轻内核定时器Swtmr:不受硬件和数量限制,满足用户需求
    FLINK基础(137):DS流与表转换(3) Handling of (Insert-Only) Streams(2)fromDataStream(FLINK1.13以上)
    FLINK基础(136):DS流与表转换(2) Handling of (Insert-Only) Streams(1)简介(FLINK1.13以上)
  • 原文地址:https://www.cnblogs.com/anjingdian/p/11073802.html
Copyright © 2011-2022 走看看