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
public System.Collections.IEnumerator GetEnumerator() {
return this.Rows.GetEnumerator();
}
//Clone方法
public override DataTable Clone() {
CustomersDataTable cln = ((CustomersDataTable)(base.Clone()));
cln.InitVars();
return cln;
}
//创建新的实例
protected override DataTable CreateInstance() {
return new CustomersDataTable();
}
//DataColumn变量初始化函数,Clone()中调用,另一种调用方式是在MyCustomers的InitVars()中调用
internal void InitVars() {
//各种DataColumn变量的初始化
this.columnCustomerID = this.Columns["CustomerID"];
this.columnCompanyName = this.Columns["CompanyName"];
this.columnContactName = this.Columns["ContactName"];
this.columnContactTitle = this.Columns["ContactTitle"];
this.columnAddress = this.Columns["Address"];
this.columnCity = this.Columns["City"];
this.columnRegion = this.Columns["Region"];
this.columnPostalCode = this.Columns["PostalCode"];
this.columnCountry = this.Columns["Country"];
this.columnPhone = this.Columns["Phone"];
this.columnFax = this.Columns["Fax"];
}
//初始化函数,初始化Columns,并添加各种约束
private void InitClass() {
this.columnCustomerID = new DataColumn("CustomerID", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnCustomerID);
this.columnCompanyName = new DataColumn("CompanyName", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnCompanyName);
this.columnContactName = new DataColumn("ContactName", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnContactName);
this.columnContactTitle = new DataColumn("ContactTitle", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnContactTitle);
this.columnAddress = new DataColumn("Address", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnAddress);
this.columnCity = new DataColumn("City", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnCity);
this.columnRegion = new DataColumn("Region", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnRegion);
this.columnPostalCode = new DataColumn("PostalCode", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnPostalCode);
this.columnCountry = new DataColumn("Country", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnCountry);
this.columnPhone = new DataColumn("Phone", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnPhone);
this.columnFax = new DataColumn("Fax", typeof(string), null, System.Data.MappingType.Element);
this.Columns.Add(this.columnFax);
this.Constraints.Add(new UniqueConstraint("Constraint1", new DataColumn[] {
this.columnCustomerID}, true));
this.columnCustomerID.AllowDBNull = false;
this.columnCustomerID.Unique = true;
this.columnCompanyName.AllowDBNull = false;
}
public CustomersRow NewCustomersRow() {
return ((CustomersRow)(this.NewRow()));
}
protected override DataRow NewRowFromBuilder(DataRowBuilder builder) {
return new CustomersRow(builder);
}
protected override System.Type GetRowType() {
return typeof(CustomersRow);
}
protected override void OnRowChanged(DataRowChangeEventArgs e) {
base.OnRowChanged(e);
if ((this.CustomersRowChanged != null)) {
this.CustomersRowChanged(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action));
}
}
protected override void OnRowChanging(DataRowChangeEventArgs e) {
base.OnRowChanging(e);
if ((this.CustomersRowChanging != null)) {
this.CustomersRowChanging(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action));
}
}
protected override void OnRowDeleted(DataRowChangeEventArgs e) {
base.OnRowDeleted(e);
if ((this.CustomersRowDeleted != null)) {
this.CustomersRowDeleted(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action));
}
}
protected override void OnRowDeleting(DataRowChangeEventArgs e) {
base.OnRowDeleting(e);
if ((this.CustomersRowDeleting != null)) {
this.CustomersRowDeleting(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action));
}
}
public void RemoveCustomersRow(CustomersRow row) {
this.Rows.Remove(row);
}
}
3)MyCustomers中定义了继承自DataRow的类CustomersRow
public class CustomersRow : DataRow {
private CustomersDataTable tableCustomers;//保留了一个对DataTable的引用
internal CustomersRow(DataRowBuilder rb) :
base(rb) {
this.tableCustomers = ((CustomersDataTable)(this.Table));//初始化引用
}
public string CustomerID {
get {
return ((string)(this[this.tableCustomers.CustomerIDColumn]));
}
set {
this[this.tableCustomers.CustomerIDColumn] = value;
}
}
public string CompanyName {
get {
return ((string)(this[this.tableCustomers.CompanyNameColumn]));
}
set {
this[this.tableCustomers.CompanyNameColumn] = value;
}
}
public string ContactName {
get {
try {
return ((string)(this[this.tableCustomers.ContactNameColumn]));
}
catch (InvalidCastException e) {
throw new StrongTypingException("无法获取值,因为它是 DBNull。", e);
}
}
set {
this[this.tableCustomers.ContactNameColumn] = value;
}
}
public string ContactTitle {
get {
try {
return ((string)(this[this.tableCustomers.ContactTitleColumn]));
}
catch (InvalidCastException e) {
throw new StrongTypingException("无法获取值,因为它是 DBNull。", e);
}
}
set {
this[this.tableCustomers.ContactTitleColumn] = value;
}
}
//……..
//以及其他可以为空字段的对应属性
public bool IsContactNameNull() {
return this.IsNull(this.tableCustomers.ContactNameColumn);
}
public void SetContactNameNull() {
this[this.tableCustomers.ContactNameColumn] = System.Convert.DBNull;
}
public bool IsContactTitleNull() {
return this.IsNull(this.tableCustomers.ContactTitleColumn);
}
public void SetContactTitleNull() {
this[this.tableCustomers.ContactTitleColumn] = System.Convert.DBNull;
}
//……..
//以及其他可以为空字段的IsXXXNull(),SetXXXNull()方法
}
可见,CustomersRow类添加了不少属性(对应于各个字段),还提供了判断是否为DBNull以及设置DBNull的操作。并且,对这些属性的所有操作其实都是转化为对DataTable相应column对象的操作。
4)MyCustomers中定义了类CustomersRowChangeEvent继承自EventArgs:
public class CustomersRowChangeEvent : EventArgs {
private CustomersRow eventRow;
private DataRowAction eventAction;
public CustomersRowChangeEvent(CustomersRow row, DataRowAction action) {
this.eventRow = row;
this.eventAction = action;
}
public CustomersRow Row {
get {
return this.eventRow;
}
}
public DataRowAction Action {
get {
return this.eventAction;
}
}
}