标题：强类型数据集
强类型数据集
强类型数据集实现为一系列的类，这些类派生自组成数据集的那些基类。派生于DataSet的强类型数据集，派生于DataTable的强类型数据表，派生于DataRow的强类型数据行。这些派生类都定义了多个附加的属性和方法，为基础类数据提供了类型安全的访问。
TypedDataSet.TypedDataTable[n]. TypedProperty
1） TypedDataSet：强类型数据集，返回强类型的数据集。
2） TypedDataSet.TypedDataTable：强类型数据表，返回强类型的数据表
3） TypedDataTable[n]：强类型索引，返回强类型数据行
4） TypedProperty：强类型列属性。列的强类型访问，返回列类型的实例。
DataSet. Tables[n]. Rows[m][ DataColumn| int |string columnName]
1） DataSet：DataSet返回。
2） Tables[n]：返回DataTable。
3） Rows[m]：返回DataRow。
4） Rows[m][ DataColumn| int |string columnName]：返回Object类型的引用。
强类型类使用了Partial类特性，Partial类允许一个类定义存在于一个项目的多个文件中。使用类允许在项目中的某个单独的文件中为强类型数据集补充代码去实现验证逻辑或商业逻辑。如果重新生成强类型数据集，这个单独文件的代码不会受到影响。1．强类型数据集中1) 强类型数据表属性
提供了对强类型数据集中强类型数据表实例的类型安全的访问。提供了类型安全，并且可以提高设计效率和运行效率（主要相对于字符串而言）。
（1） DataSet中,Tables索引器（通过集合访问）
public DataTable this [string name| int index] { get; }
DataTable employees = dataset.Tables[“Employees”|0];
（2） 强类型数据集中，强类型数据表属性（通过私有数据成员tableEmployees来访问表对象）
public EmployeesDataTable Employees
{
get {return this.tableEmployees;}
}  
EmployeesDataTable employees = dataset. Employees;2．强类型数据表中1） DataColumn的命名属性
对于数据表中的每个列，都有一个对应类型为DataColumn的命名属性，这些属性可以通过名称来获得这些数据列的类型信息访问。可以提高设计效率和运行效率（主要相对于字符串而言）。
（1） DataTable中, Columns索引器（通过集合访问）
public DataColumn this [string name| int index] { get; }
DataColumn employeeIDColumn = dataset.Tables[“EmployeeID”|0];
(2)  强类型数据表中，DataColumn的命名属性（通过私有数据成员访问）
public global::System.Data.DataColumn EmployeeIDColumn
{
get { return this.columnEmployeeID;  }
}
DataColumn employeeIDColumn = dataset. EmployeeIDColumn;
2) 迭代访问及强类型索引器（均访问数据行集合）
强类型数据表提供了一个强类型数据行索引器，通过它可以用类型安全的强类型数据表类的实例访问表中的所有强类型数据行。提供了类型安全。
实现了迭代接口IEnumerable,可以迭代访问表中的所有强类型数据行。
（1） DataTable中, 未实现迭代接口IEnumerable，无DataRow索引器和Count属性，不能直接迭代访问表中的数据行，只能通过数据行集合迭代访问表中的数据行。
public DataRow this [int index { get; }
public override int Count { get; }
（2） 强类型数据表中，实现了迭代接口IEnumerable,实现了实例迭代访问。类型安全的索引器、Count属性（与迭代访问无关）。
强类型数据表中，类型安全的索引器，返回强类型数据行。
public EmployeesRow this[int index]
{
get { return ((EmployeesRow)(this.Rows[index])); }
}
强类型数据表中，Count属性，返回数据行的数量。
public int Count
{
get { return this.Rows.Count; }
}
强类型数据表中，IEnumerable.GetEnumerator接口方法，
返回IEnumerator接口变量。强类型数据表中的迭代访问与通过数据行集合迭代访问表中的数据行本质上是一样的。
public virtual IEnumerator GetEnumerator() 
{
return this.Rows.GetEnumerator();
}
foreach (NorthwindDataSet.CustomersRow rowCustomer in dsNorthwind.Customers) {}
foreach (NorthwindDataSet.CustomersRow rowCustomer in dsNorthwind.Rows) {}
3) 类型安全的方法
（1） NewEmployeesRow，创建一个强类型的新的数据行
public EmployeesRow NewEmployeesRow() 
{
return ((EmployeesRow)(this.NewRow()));
}
（2） AddEmployeesRow，在数据行集合中插入一个强类型的新的数据行
public void AddEmployeesRow(EmployeesRow row) 
{
this.Rows.Add(row);
}
4) 强类型事件
public event EmployeesRowChangeEventHandler EmployeesRowChanging;
public event EmployeesRowChangeEventHandler EmployeesRowChanged;            
public event EmployeesRowChangeEventHandler EmployeesRowDeleting;
public event EmployeesRowChangeEventHandler EmployeesRowDeleted;
public delegate void EmployeesRowChangeEventHandler(object sender, EmployeesRowChangeEvent e);
public class EmployeesRowChangeEvent : global::System.EventArgs 
{            
private EmployeesRow eventRow;            
private global::System.Data.DataRowAction eventAction;            
public EmployeesRowChangeEvent(EmployeesRow row, 
System.Data.DataRowAction action) 
{
this.eventRow = row;
this.eventAction = action;
}
public EmployeesRow Row
{
get { return this.eventRow; }
}
public global::System.Data.DataRowAction Action 
{
get { return this.eventAction;}
}      
}3．强类型数据行中1) 通过强类型的属性显示行中的每一列的值
（1） 通过DataRow索引器显示行中的每一列的值（通过集合访问）
public Object this [DataColumn| int |string columnName] 
{ get; set; }
（2） 通过强类型的列属性显示行中的每一列的值
没有任何硬编码的架构引用，没有表名或列明的任何字符串文本，而且也不需要按列的位置来索引访问列。都是通过强类型行对象显示的强类型列属性来访问的。
public string FirstName {
get {
return ((string)(this[this.tableEmployees.FirstNameColumn]));
}
set {
this[this.tableEmployees.FirstNameColumn] = value;
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public bool IsBirthDateNull() {
return this.IsNull(this.tableEmployees.BirthDateColumn);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void SetBirthDateNull() {
this[this.tableEmployees.BirthDateColumn] = global::System.Convert.DBNull;
}
public EmployeesRow[] GetEmployeesRows() {
if ((this.Table.ChildRelations["FK_Employees_Employees"] == null)) {
return new EmployeesRow[0];
}
else {
return ((EmployeesRow[])(base.GetChildRows(this.Table.ChildRelations["FK_Employees_Employees"])));
}
}
（3） 通过方法校验数据列是否为空。
public bool IsCustomerIDNull() {
return this.IsNull(this.tableOrders.CustomerIDColumn);
}
2） 关系导航 
public EmployeesRow EmployeesRowParent {
get {
return ((EmployeesRow)(this.GetParentRow(this.Table.ParentRelations["FK_Employees_Employees"])));
}
set {
this.SetParentRow(value, this.Table.ParentRelations["FK_Employees_Employees"]);
}
}
二．创建强类型数据集的方法
设计器生成 .XSD、.XSC、.XSS 三个文件，然后用代码生成工具将.XSD文件生成强类型数据集。
1） 使用“数据源”窗口
2） 使用“数据集设计器”
3） 基于DataAdapter
三．强类型数据集的优点
通过强类型对象的强类型属性来进行访问。可以更加容易和清晰的访问到它们。通过这些方法和属性，就算架构发生了改变，代码也不一定非要更改不可。
应该尽量将非类型化的变量引用强制转化为强类型的变量引用。（例如使用基类的方法，返回的是非类型化的变量引用，应该强制转化为强类型的变量引用）
1． 效率
1） 设计（编程）效率
IntelliSense。可以得到强类型在属性和方法上添加的完整的IntelliSense的支持。
拖放功能。
2） 运行效率
例如：强类型列属性均通过对象（运行效率最高）来访问，而不是通过位置索引（运行效率稍次）或字符串名来访问（运行效率最低）
2． 可维护性
数据库架构改变：强类型数据集使C#编译器可以保证找到所有受影响的代码行。在弱类型数据集，可能漏掉一些地方没有修改过来，而且直到运行的时候才会发现。
1） 数据库列的名称发生改变
例如：将Phone列的名称改变为PhoneNo。
（1） 重新生成强类型程序集后，引用Phone属性的每个地方，C#编译器报错，
a． 可以在任务窗格中点击编译错误进行修改成PhoneNo属性。
b． 做一个全局的查找和替换
c． 使用VS2005的重构工具
（2） 重新生成强类型程序集后，在数据集设计器中Name属性（在DataTable的列集合中列的名称string类型）改回为Phone，而保留Source属性（在DataColumnMapping中的SourceColun的名称string类型）为PhoneNo不变。
2） 数据库列的数据类型发生改变
例如：将Phone列的类型由Int类型改变为String类型。
引用Phone列的每个地方，C#编译器报错，
3． 类型安全性
DataTable中的数据类型可以做运行时的类型检查。DataRow类的索引器，简单的显示为Object类型的引用，这意味着代码在设计时可以将任何类型的数值赋予数据列，C#编译器不可能知道究竟是会成功还是失败。使用强类型，在设计其间，C#编译器就可能检测出类型不兼容的问题。编译器会防止将不正确的类型赋予某个列。可以确保不会访问一个不存在的元素。
表数据适配器，提供了一个类型安全的方法用于从数据库中填充数据集。
生成更新逻辑的方法
1． 手动配置SqlDataAdapter对象生成更新逻辑
2． 使用SqlCommandBuilder对象生成更新逻辑
3． 使用VS[TableAdapte配置向导] 生成更新逻辑
4． 使用VS[DataAdapte配置向导] 生成更新逻辑