C#中DataSet,DataTable,DataView的区别与用法

一、创建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对象的数组

  • Select()
  • Select(string filterExpression)
  • Select(string filterExpression, string sort)
  • 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"

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#使用DataSet Datatable更新数据库的三种实现方法

    本文以实例形式讲述了使用DataSet Datatable更新数据库的三种实现方法,包括CommandBuilder 方法.DataAdapter 更新数据源以及使用sql语句更新.分享给大家供大家参考之用.具体方法如下: 一.自动生成命令的条件 CommandBuilder 方法 a)动态指定 SelectCommand 属性 b)利用 CommandBuilder 对象自动生成 DataAdapter 的 DeleteCommand.InsertCommand 和 UpdateCommand

  • C#中的DataSet、string、DataTable、对象转换成Json的实现代码

    C#中对象,字符串,dataTable.DataReader.DataSet,对象集合转换成Json字符串方法. public class ConvertJson { #region 私有方法 /// <summary> /// 过滤特殊字符 /// </summary> /// <param name="s">字符串</param> /// <returns>json字符串</returns> private s

  • C#实现XML文件与DataTable、Dataset互转

    一.DataTable转XML #region DataTableToXml /// <summary> /// 将DataTable对象转换成XML字符串 /// </summary> /// <param name="ds">DataSet对象</param> /// <returns>XML字符串</returns> public static string DataTableToXml(DataTable

  • C#中把DataTable、Dataset转Json数据

    什么是JSON JSON是JavaScript Object Notation的简称,中文含义为“JavaScript 对象表示法”,它是一种数据交换的文本格式,而不是一种编程语言. JSON 是一种轻量级的数据交换格式,它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据.简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言.易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率. JSON的特点 JSON 主要

  • C#中LINQ to DataSet操作及DataTable与LINQ相互转换

    一.DataTable的扩展方法: 1.DataTable转Linq:AsEnumerable 方法 返回的EnumerableRowCollection<DataRow> 实现了 IEnumerable<T>接口.其中泛型参数T是DataRow. 此对象可用在 LINQ表达式或方法查询中. 语法: public static EnumerableRowCollection<DataRow> AsEnumerable (this DataTable source); 在

  • C#中DataSet,DataTable,DataView的区别与用法

    一.创建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=t

  • JavaScript中click和onclick本质区别与用法分析

    本文实例讲述了JavaScript中click和onclick本质区别与用法.分享给大家供大家参考,具体如下: 原生javascript的click在w3c里边的阐述是DOM button对象,也是html DOM click() 方法,可模拟在按钮上的一次鼠标单击. button 对象代表 HTML 文档中的一个按钮.button元素没有默认的行为,但是必须有一个 onclick 事件句柄以便使用. 语法:buttonObject.click() <html> <head> &l

  • JavaScript中callee和caller的区别与用法实例分析

    本文实例讲述了JavaScript中callee和caller的区别与用法.分享给大家供大家参考,具体如下: 1.callee 在函数的内部,有两个特殊的对象:arguments和this.其中arguments是一个类似数组的对象,包含着传入函数的所有参数. 虽然arguments的主要用途是保存函数参数,但这个对象有一个属性--callee,该属性是一个指针,指向拥有这个arguments对象的函数 所以callee的作用就是来指向当前对象 看一个阶层函数的例子就会明白他的用途了: /* *

  • js中apply()和call()的区别与用法实例分析

    本文实例讲述了js中apply()和call()的区别与用法.分享给大家供大家参考,具体如下: 每个函数都包括两个非继承而来的方法:apply()和call().两者用途都是在特定的作用域中调用函数,等于重新设置了函数体内this对象的值. 两者区别仅在于接收参数方式不同,apply()第一个参数是调用apply的函数运行的作用域,的第二个参数可以是Array的实例(数组),也可以是arguments对象,call()第一个参数是this的值没有变化,而其余参数都直接传递给函数(也就是逐个列举出

  • Vue 中 filter 与 computed 的区别与用法解析

    watch与computed.filter: watch:监控已有属性,一旦属性发生了改变就去自动调用对应的方法 computed:监控已有的属性,一旦属性的依赖发生了改变,就去自动调用对应的方法 filter:js中为我们提供的一个方法,用来帮助我们对数据进行筛选 watch与computed的区别: 1.watch监控现有的属性,computed通过现有的属性计算出一个新的属性 2.watch不会缓存数据,每次打开页面都会重新加载一次, 但是computed如果之前进行过计算他会将计算的结果

  • C#中Hashtable和Dictionary的区别与用法示例

    前言 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对,其中key通常可用来快速查找,同时key是区分大小写:value用于存储对应于key的值.Hashtable中keyvalue键值对均为object类型,所以Hashtable可以支持任何类型的keyvalue键值对. Hashtable与Dictionary,都是key/value键值对的形式,区别在于Hashtable的键值是ob

  • vue中LocalStorage与SessionStorage的区别与用法

    目录 什么是LocalStorage 什么是SessionStorage LocalStorage与SessionStorage的区别 LocalStorage与SessionStorage的特点 LocalStorage与SessionStorage的用法 LocalStorage与SessionStorage应用实例 前面把后台的验证机制梳理了一下,主要是Cookie.Session和Token的使用,Django:Cookie设置及跨域问题处理.Django实:Cookie搭配Sessio

  • python中sort()和sorted()的区别及用法实例

    目录 一. 二. python中输入字符串转列表的注意问题 总结 本文主要讲sort与sorted的主要区别,以便正确使用 一. sort()只能用于列表:sorted()可以用于所有可迭代对象: 比如: str_a = "blue" print(sorted(str_a)) >>>['b', 'e', 'l', 'u'] 二. sort()对列表排序是进行原处排序,并不会返回新的列表: sorted()排序后会返回一个新的列表: 比如: 对于sort()来说: li

  • Shell编程中while与for的区别及用法详解

    在shell编程中经常用到循环,常用的循环有for和while循环两种.while循环默认以行读取文件,而for循环以空格读取文件切分文件,本篇就结合现网的一些使用示例说说二者的用法和区别. 一.常用语法 1.for循环 for循环常用的语法结构有如下几种: for 变量 in seq字符串 for 变量 in `command` " " for 变量 in "$@"或"$*" for((赋值:条件:运算语句)) 2.while循环 while循

  • C++中nullptr 和 NULL 的区别及用法

    1. 为什么会有nullptr的出现 目的:nullptr的出现主要是为了替代NULL. 那么,为什么要替代NULL呢? 在NULL的定义中存在会有2种方式,有的编译器会将NULL定义成0,有的编译器会将NULL定义成((void*)0). 那么,这两种定义方式会对c++有什么区别呢? 在c++中不允许( void* )隐式的转成其他类型,在某些编译器把NULL定义成((void*)0)的情况下,当你定义变量去赋值NULL时候,NULL就会变定义为0. 另外,这种问题也会对c++的重载特性造成混

随机推荐