• C#(99):DataSet,DataTable,DataView、DataRelation


    image

    一、创建Dataset和DataTable

    DataSet ds = new DataSet();//DataSetName默认为"NewDataSet"
    DataTable table = ds.Tables.Add("Customers");
    //或者
    //DataTable table1 = new DataTable("Customers");
    //ds.Tables.Add(table1);
    
    //添加列 
    DataColumn col=table.Columns.Add("OrderID",typeof(int)) ;//Type.GetType("System.Int32")
     col.AllowDBNull=false;
     col.MaxLength=5;
     col.Unique = true;//为此列自动添加一个UniqueConstraint约束
    table.PrimaryKey = new System.Data.DataColumn[] {table.Columns["CustomerID"]};//设置主键,AllowDBNull自动设成false,自动应用UniqueConstraint约束
    
    //自动增长列
    DataColumn col1=table.Columns.Add("OrderID",typeof(int));
     col.AutoIncrement=true;
     col.AutoIncrementSeed=1;
     col.AutoIncrementStep=1;
     col.ReadOnly=true;
    
    //计算列
    table.Columns.Add("ItemTotal",typeof(decimal),"Quantity*Unique");

    二、添加行

    //使用DataRowCollection对象的Add()方法
    DataRow row = ds.Tables[0].NewRow();
    row["CustomerID"] = "ALFKI";
    row["CustomerName"] = "XX";
    ds.Tables[0].Rows.Add(row);
    
    //使用Table对象的LoadDataRow方法
    object[] rowData = { "ALFKI", "XX", "x", "" };
    ds.Tables[0].LoadDataRow(rowData, false);

    三、修改行

    //使用DataRow对象的BeginEdit、EndEdit方法。
    DataRow row = ds.Tables[0].Rows.Find("ANTON");//在主键列查找,可以用索引访问行ds.Tables[0].Rows[3]
    if (row != null)
    {
        row.BeginEdit();
        row["CompanyName"] = "New Company";
        row["ContactName"] = "New Contact";
        row.EndEdit();
    }
    //使用DataRow对象ItemArray属性进行赋值。
    objec[] rowData = { null, "New Company", "New Contact", null };//null表示不修改该列数据
    DataRow row = ds.Tables[0].Rows.Find("ALFKI");
    row.ItemArray = rowData;
    
    //单个字段修改
    if (row.IsNull("phone"))
    {
        row["phone"] = DBNull.Value;
    }//判断字段值是否为空,是则赋予空值。

    四、删除行

    //Delete方法实际上不是从DataTable中删除掉一行,而是将其标志为删除.
    //循环删除的时候最好用Delete方法,这样先做删除标记,然后用table.AcceptChanges()方法统一提交,或者RejectChanges()  方法实现行状态的回滚
    DataRow[] rows = ds.Tables[0].Select("Compane like 'a%'");
    foreach (DataRow row in rows)
    {
        row.Delete();
    }
    ds.Tables[0].AcceptChanges();
    //如果该行的 RowState 为 Added,则在调用 Delete后, RowState 将变为 Detached。  在调用 AcceptChanges 之后,将从表中移除该行。
    //如果该行的 RowState 为 Unchanged,则在调用 Delete后,RowState 将变为 Deleted。  在调用 AcceptChanges 之后,将从表中移除该行。
    
    
    //Remove和RemoveAt方法则是真正的从DataRow中删除一行,等同于先调用 DataRow.Delete() 方法再调用 AcceptChanges()方法。DataRowState状态改变两次。
    DataRow row = ds.Tables[0].Rows.Find("ALFKI");
    ds.Tables[0].Rows.Remove(row);//ds.Tables[0].RemoveAt(index)
    
    //Clear方法
    ds.Tables[0].Clear();
    ds.Clear();

    数据行状态 (RowState)

    • UnChanged状态:指表中的行自创建之后没有做过任何改动的状态,或则是行在上次接受修改之后,至今未做过任何改动的状态。
    • Added状态:该状态是指已经将行添加到表中,但是尚未调用表对象的AcceptChanged方法。调用AcceptChanged方法时,所有处在Added状态的行都变为Unchanged状态。
    • Modified状态:该状态表示该行已经被修改。调用AcceptChanged方法时,所有处在Modified状态的行都变为Unchanged状态
    • Deleted状态:该状态表示该行已经从表中删除,但是尚未调用表对象的AcceptChanged方法
    • Detached状态:该状态表示该行不属于任何表,或则已经从表中分离出去了,不再属于任何表的DataRow对象。

      新建的行(DataRow对象)处于Detached状态,把它添加到DataTable对象之后,该DataRow对象的状态变为Added状态。如果对该DataRow进行了修改,则该行处于Modified状态。如果使用Remove方法从表中移除该DataRow对象,或则使用Delete方法和AcceptChanged方法移除该行,则该行处于Detached状态。

    五、合并两个DataSet

    //将指定的 dataSet、datatable或datarow[] 与当前的 ds 合并,在此过程中,将根据给定的参数保留或放弃在当前 ds 中的更改并处理不兼容的架构。
    ds. Merge (DataSet otherDataSet, bool preserveChanges, System.Data.MissingSchemaAction missingSchemaAction);

    preserveChanges:当两个数据集包含相同主键值的记录时,是否保留当前ds的更改,默认为false。

    • false:用otherDataSet的记录来更新当前ds记录。ds存在而otherDataSet不存在的主键行结果将被删除。
    • true:保留ds的记录,并加入新记录。

    MissingSchemaAction:当两个数据集包含不同的列时(两个具有不同模式的DataSet)的处理方法。

    • Add:   添加otherDataSet的新列到ds.
    • AddWithKey :   添加otherDataSet的新列和主键信息到ds.
    • Error :  如果缺少指定的列映射,则生成 InvalidOperationException。
    • Ignore :   忽略任何新列。
    ds.Tables[0].Merge(dataSet.Tables[0], false, MissingSchemaAction.Add);

    六 、添加关系

    ds.Relations.Add("CustomerToOrders",//关系名:默认关系名为DataRelation
        ds.Tables["Customer"].Columns["CustomerID"],//父列,可为数组
        ds.Tables["Orders"].Columns["CustomerID"]//子列,可为数组
    );

    注意:默认会创建UniqueConstraint到父表,ForeignKeyConstraint约束到子表。
    可以使用DataRelation的一个构造函数的参数俩避免自动创建约束。

    //从父行获取子行:GetChildRows
     DataRow[] rows = ds.Tables["Customer"].Rows[0].GetChildRows("CustomerToOrders");//CustomerToOrders为关系名。
    //从子行获取行行:GetChildRows    或或者GetParentRow                                                                    
     DataRow[] rows = ds.Tables["Orders"].Rows[0].GetParentRows("CustomerToOrders");//
     //获取不同的行版本:
    if (rows[0].HasVersion(DataRowVersion.Proposed)
     {
         rows = rows[0].GetChildRows("CustomerToOrders", DataRowVersion.Proposed);
     }

    数据行版本(DataRowVersion)

      • Current:表示行的当前值。处于deleted状态的行不存在该行版本。
      • Original:表示行的原始值。处于Added状态的行不存在该行版本
      • Proposed:表示行的建议值。不属于表的行,即处于Detached状态的行存在该行版本;对于正在进行编辑的行,也存在该行版本。
      • Default:表示行的默认版本。处于Added,Modified或则Unchanged状态的行的默认行版本是Current;处于deleted状态的行的默认行版本是Original。处于Detached状态的行的默认版本是proposed。

    当调用AcceptChanged方法,所有处于deleted状态的行将变为Detached状态,即被移除。其余的行会变为Unchanged状态,并且Original版本中的值会改写为Current行版本的值。

    七、数据约束。

    1、主键约束,使用UniqueConstraint

    UniqueConstraint unique = new UniqueConstraint(ds.Tables[0].Columns["phone"]);
    ds.Tables[0].Constraints.Add(unique);

    2、外键约束:ForeignKeyConstraint

    ForeignKeyConstraint fk = new ForeignKeyConstraint("CustomerOrder",
            ds.Tables["Customer"].Columns["CustomerID"],//父列,可为数组
            ds.Tables["Orders"].Columns["CustomerID"]//子列,可为数组
    );
    fk.UpdateRule = Rule.Cascade;
    fk.DeleteRule = Rule.SetNull;
    fk.AcceptRejectRule = Rule.None;
    ds.Tables["Orders"].Constraints.Add(fk);//在字表中添加约束,且目标自动添加Unique约束。

    在对附表的列或行执行某种操作时,使用这些规则一确定应对子表行进行的操作规则。

    • Rule.Cascade:级联(默认);
    • Rule.None(无动作);
    • Rule.SetDefault;
    • Rule.SetNull四种。

    注意:启用约束前提是:

    ds.EnforceConstraints = true;//true为默认值

    在对DataSet执行AcceptChanges或RejectChanges方法时,才执行AccpetRejectRule。比UpdateRule和DeleteRule要晚执行。

    八、DataTable事件

    • dt.ColumnChanging
    • dt.ColumnChanged 
    • dt.RowChanging
    • dt.RowChanged
    • dt.RowDeleting
    • dt.RowDeleted
    • dt.TableClearing
    • dt.TableCleared
    • dt.TableNewRow
    custTable.ColumnChanged += new  DataColumnChangeEventHandler(Column_Changed );
    private static void Column_Changed(object sender, DataColumnChangeEventArgs e )
    {
        Console.WriteLine("Column_Changed Event: name={0}; Column={1}; original name={2}", 
            e.Row["name"], e.Column.ColumnName, e.Row["name", DataRowVersion.Original]);
    }

    九、DataSet其他方法

    ds.Clone();//只克隆一个相同结构的Dataset
    ds.Copy();//复制一个相同结构和相同内容的Dataset
    
    ds.ReadXml("D:1.xml");
    ds.ReadXmlSchema("D:1.xml");
    ds.WriteXml("D:1.xml",XmlWriteMode.WriteSchema);
    ds.WriteXmlSchema("D:1.xml");
    
    ds.GetXml()://返回模式和内容的XML
    ds.GetXmlSchema://只返回模式信息
     
    DataTable dt;
    dt.Compute(expression,filter); //计算
    dt.Select(filter,sort,DataViewRowState)

    十、DataTable的Select()方法

    获取DATAROW对象的数组

    1. Select()
    2. Select(string filterExpression)
    3. Select(string filterExpression, string sort)
    4. Select(string filterExpression, string sort, DataViewRowState recordStates)

    注意事项:上面的Select操作是大小写不敏感的(记录的字段不敏感),如果需要区分大小写,需要将DataTable的caseSensitive属性设为true。

    DataRow[] arrRows = table.Select("pubdate>='#1/1/2000#'");//下面这条语句选择Pubdate字段日期在2000年1月1日当天或之后的DataRow 
    
    DataRow[] arrRows = table.Select("state in('ca','tn','wa')");//支持in, 返回"state"等于CA、TN或WA的所有行
    
    DataRow[] arrRows = table.Select("state like 'ca*'");//支持like   
    
    DataRow[] arrRows = table.Select("isnull(state,0)=0");//还可以使用一些Sql函数,在DataTable中选择State字段为空的记录
    
    DataRow[] arrRows = table.Select("state='tn' and zip like '37*'");//还可以使用And、Or和Not
    
    DataRow[] arrRows = table.Select("id>5", "id desc");
    //带过滤、排序和行状态的完整方法:
    DataRow[] arrRows = table.Select("id>5", "id desc", DataViewRowState.Added);


    十一、DataView数据视图

    //创建数据视图DataView 
    DataView dv = ds.Tables["Author"].DefaultView;//或者DataView dv = new DataView(ds.Tables["Author"]);
    

    //行过滤
    dv.RowFilter = "state='CA' and City=aa";//行过滤,日期需要用#号包围。或者dv.RowFilter = "Sum(child.unitPrice>100)"//可用的函数Convert,Len,IsNull,IIF,SubString
    dv.RowStateFilter = DataViewRowState.Added | DataViewRowState.OriginalRows;
    
    
    //主键查找
    int rowIndex = dv.Find("wison");//注意查找获取行索引。
    DataRowView[] rowviews = dv.FindRows("Raing");
    
    
    //字段排序
    dv.Sort = "state desc,firstName asc"; 

    //添加行
    dv.AllowNew = true;
    DataRowView newRow = dv.AddNew();
    newRow["customername"] = "aa";
    
    
    //修改行
    dv.AllowEdit = true;
    dv[0]["customername"] = "aa";
    
    
    //删除行
    dv.AllowDelete = true;
    dv.Delete(1);
    
    
    //遍历
    foreach (DataRowView rowview in dv)
    {
        rowview["customername"] = "aa";
    }

    DataView的行状态(DataViewRowState)

    • Added:    新行。
    • CurrentRows:   当前行包括未更改的行、新行和已修改的行。 (默认情况下,DataViewRowState 设置为 CurrentRows。)
    • Deleted:    已删除的行。
    • ModifiedCurrent:    已修改的原始数据的当前版本
    • ModifiedOriginal:    已修改数据的原始版本。
    • None:    无。
    • OriginalRows:    原始行包括未更改的行和已删除的行。
    • Unchanged:    未更改的行。
       

    十二、DataViewManager

    DataViewManager manager=ds.DefaultViewManager;//或new DataViewManager(ds)
    DataView dv=manager.CreateDataView(ds.Tables[0]);//创建DataView
    //或者
    manager.DataViewSettings["Order"].Sort="orderDate desc"
  • 相关阅读:
    数据结构学习
    古兰查询 之查询页面隐藏
    Qt只QSetting
    学习下知然网友写的taskqueue
    producter-consumer 他山之石
    unix缓冲
    Buffering of C streams
    POCO Log库
    linux下open和fopen的区别
    dup2替换
  • 原文地址:https://www.cnblogs.com/springsnow/p/9433966.html
Copyright © 2020-2023  润新知