Strongly Typed DataSet 优缺点
使用强类型DataSet
MyCustomers myCustomers=new MyCustomers();
MyCustomers.CustomersDataTable tblCustomers= myCustomers.Customers;
MyCustomers.CustomersRow rowCustomers=tblCustomers.NewCustomersRow();
rowCustomers.XXX=”xxx”;
//….
tblCustomers.AddCustomersRow(rowCustomers);
结合vs.net的自动完成功能可以大大提高开发效率。
强类型DataSet优缺点
优点:
1) 设计时的优势,编写代码容易,能够充分利用vs.net的自动完成功能
2) 能更容易地在设计时绑定控件
3) 运行时可以提高应用程序的性能
这主要是因为在访问某条记录的某个字段时,使用DataColumn对象本身比使用列名具有更高的效率,但增加了维护的困难。强类型的DataSet替我们解决了这个问题。
缺点:
不灵活。
1) 因为架构信息已经硬编码进MyCustomers.cs,如果发生改动的话,必须重新生成。
2) 比如从拥有30个字段的某个表中选择3个字段A,B,C,专门为这三个字段生成一个强类型的DataSet1是可以的,但是倘若另一个方法需要选择字段C,D,E,还需要为这三个字段专门生成一个强类型的DataSet2。倘若select的字段由使用者自行定制,字段的一个组合就了不得了。
3) 为避免上面使用多个强类型DataSet的情况,我们可以只使用一个强类型DataSet,这样每次不管我们Fill多少个字段,都填充进一个强类型DataSet。
但这又带来了新的问题:
i)空间的浪费(特别是对于多表连接的情况)。可以写代码测试一下30个string字段中只填充1,2个占用的空间相对大小(使用强类型DataSet比弱类型占用内存大数倍不止)。
ii)约束的违反。强类型在生成时已经把数据库中的约束(如非空,FK等)添加了进来,这样在只填充部分数据时可能会发生违反约束的异常。
比如col1,col2,col3,col4都要求不为空,但是我只select了col1,col2进入强类型DataSet,这样对应记录的col3,col4字段均为空,违反了非空约束,会抛出异常并提示:
未处理的“System.Data.ConstraintException”类型的异常出现在 system.data.dll 中。
其他信息: 未能启用约束。一行或多行中包含违反非空、唯一或外键约束的值。
尽管可以设置DataSet的EnforceConstraints属性,但是用起来还是不爽。
所以,强弱类型DataSet恐怕还得结合着用,或者放弃使用强类型DataSet。
Strongly Typed DataSet(2) ——生成代码分析
生成代码分析
生成示例DataSet
以Microsoft的Northwind的表Customers为例生成一个强类型的DataSet:
1)新建一个DataAdapter,使用的sql语句为
select * from Customers
2)使用该DataAdapter建立数据集MyCustomers
2.2.2 查看代码
我们可以发现,vs.net添加了一个MyCustomers.xsd文件,如果选择查看所有文件,还可以看到对应有一个MyCustomers.cs文件。
//MyCustomers.cs
1)定义了一个继承自DataSet的类MyCustomers
除了定义2),3),4)中的类外,主要是维护了一个对tableCustomers的引用
2)MyCustomers中定义了继承自DataTable的类CustomersDataTable
public class CustomersDataTable : DataTable, System.Collections.IEnumerable {
//为每个字段定义了相应的DataColumn对象,通过属性访问。使用DataColumn可以提高访问效率
private DataColumn columnCustomerID;
private DataColumn columnCompanyName;
private DataColumn columnContactName;
private DataColumn columnContactTitle;
//其他字段的DataColumn对象
internal CustomersDataTable() :
base("Customers") {
this.InitClass();
}
internal CustomersDataTable(DataTable table) :
base(table.TableName) {
//根据table设置本类的对应属性
if ((table.CaseSensitive != table.DataSet.CaseSensitive)) {
this.CaseSensitive = table.CaseSensitive;
}
if ((table.Locale.ToString() != table.DataSet.Locale.ToString())) {
this.Locale = table.Locale;
}
if ((table.Namespace != table.DataSet.Namespace)) {
this.Namespace = table.Namespace;
}
this.Prefix = table.Prefix;
this.MinimumCapacity = table.MinimumCapacity;
this.DisplayExpression = table.DisplayExpression;
}
[System.ComponentModel.Browsable(false)]
//Count属性
public int Count {
get {
return this.Rows.Count;
}
}
//上面各种DataColumn对应的属性
internal DataColumn CustomerIDColumn {
get {
return this.columnCustomerID;
}
}
internal DataColumn CompanyNameColumn {
get {
return this.columnCompanyName;
}
}
internal DataColumn ContactNameColumn {
get {
return this.columnContactName;
}
}
internal DataColumn ContactTitleColumn {
get {
return this.columnContactTitle;
}
}
//索引,返回对应的CustomersRow
public CustomersRow this[int index] {
get {
return ((CustomersRow)(this.Rows[index]));
}
}
public event CustomersRowChangeEventHandler CustomersRowChanged;
public event CustomersRowChangeEventHandler CustomersRowChanging;
public event CustomersRowChangeEventHandler CustomersRowDeleted;
public event CustomersRowChangeEventHandler CustomersRowDeleting;
//使用CustomersRow对象添加一行
public void AddCustomersRow(CustomersRow row) {
this.Rows.Add(row);
}
//使用各个字段的值填充一个新行
public CustomersRow AddCustomersRow(string CustomerID, string CompanyName, string ContactName, string ContactTitle, string Address, string City, string Region, string PostalCode, string Country, string Phone, string Fax) {
CustomersRow rowCustomersRow = ((CustomersRow)(this.NewRow()));
rowCustomersRow.ItemArray = new object[] {//使用ItemArray属性设置CustomersRow的值
CustomerID,
CompanyName,
ContactName,
ContactTitle,
Address,
City,
Region,
PostalCode,
Country,
Phone,
Fax};
this.Rows.Add(rowCustomersRow);
return rowCustomersRow;
}
//通过CustomerID查找CustomersRow
public CustomersRow FindByCustomerID(string CustomerID) {
return ((CustomersRow)(this.Rows.Find(new object[] {
CustomerID})));
}
//返回Enumerator