弱类型DataSet的缺点
一、只能通过列名引用,如果列名写错了编译时不会提示,只有在运行时才能知道,因此开发必须记着列名。
例如:myDataSet.Tables[0].Rows[0]["FAge"]
错写成:myDataSet.Tables[0].Rows[0]["Age"]
二、从DataSet中获取的字段的值都是object类型,在使用时必须进行类型转换,易出错。
例如:int age=Convet.ToInt32(myDataSet.Rows[0]["FAge"]);
复杂情况下,FAge、FName在数据库中可能定义成其他类型,转换过程中可能会出错。
三、将DataSet、DataTable传递给其他使用者,使用者难以识别有哪些列可以被使用。
四、运行时才能知道所有列名,数据绑定麻烦,无法使用Winform、ASP.Net的快速开发功能。
强类型DataSet
第一种:
手动写强类型DataSet
对照表定义一个类,将表内的字段写成类的属性。
例如:
添加->类->表名Row.cs->继承自DataRow->using System.Data;
class T_PersonRow:DataRow { public int Id { get { return Convert.ToInt32(this["FId"]); } set { this["FId"] = value; } } public string Name { get { return Convert.ToInt32(this["FName"]); } set { this["FName"] = value; } } public int Age { get { return Convert.ToInt32(this["FAge"]); } set { this["FAge"] = value; } } }
第二种:
Visual Studio自动生成强类型DataSet
添加->数据->数据集->将需要强类型化的表拖入
private void btnTypedDataSet_Click(object sender, EventArgs e) { T_PersonTableAdapter typedAdapter = new T_PersonTableAdapter(); _5_ADO.Net_DataSet尝试封装.DataSet1.T_PersonDataTable typedDataTable=typedAdapter.GetData(); for (int i = 0; i < typedDataTable.Count; i++) { _5_ADO.Net_DataSet尝试封装.DataSet1.T_PersonRow typedRow = typedDataTable[i]; MessageBox.Show(typedRow.FName + typedRow.FAge); } }
注意:拖动只是根据表的结构生成一个强类型DataSet,并没有把表内数据拖入。拖入后,自动生成app.config文件
注意:Properties->Settings.settings
注意:使用类型化DataSet一定要有主键
注意:定义在别的类内的类调用时需要写全名。(一般情况下,我们不在类内声明类,这里是自动生成的)例如:
T_PersonDataTable和T_PersonRow都是定义在DataSet类内部的,调用时使用全名_5_ADO.Net_DataSet尝试封装.DataSet1.T_PersonDataTable以及_5_ADO.Net_DataSet尝试封装.DataSet1.T_PersonRow
强调,这里点出来的不是属性,而是类
调用类型化DataSet
第一步
T_PersonsTableAdapter typedAdapter = new T_PersonsTableAdapter();
using _5_ADO.Net_类型化DataSet.DataSetPersonsTableAdapters;
第二步
调用typedAdapter.GetData()方法返回_5_ADO.Net_类型化DataSet.DataSetPersons.T_PersonsDataTable类型的表
注意:区别GetData()方法与Fill()方法
GetData():返回一个新的table
Fill():添加到已有的table中
_5_ADO.Net_类型化DataSet.DataSetPersons.T_PersonsDataTable typedDataTable = typedAdapter.GetData();
第三步
for(int i=0;i<typedDataTable.Count;i++)
{
_5_ADO.Net_类型化DataSet.DataSetPersons.T_PersonsRow personRow = typedDataTable[i];
string msg = string.Format("姓名:{0};年龄:{1}", personRow.Name, personRow.Age);
MessageBox.Show(msg);
}
即:T_PersonsTableAdapter ->T_PersonsDataTable ->T_PersonsRow
前面使用自动生成的TableAdapter的GetData()方法来获取数据,等同于执行select * from T_表,即把所有数据取出来。接下来,讨论如何修改强类型DataSet以及如何将修改完成的结果传回数据库。
调用Adapter的Update()方法就可以将DataSet的改变保存到数据库。
注意:要调用Update、Delete等方法必须设置数据库主键。
忘了设置主键的补救措施:
第一步:数据库中设置主键
第二步:.xsd文件内T_表->右键配置->完成
第三步:增减字段->查询生成器->字段选项
插入新行
调用Adapter.Insert();
删除某行
调用Adapter.Delete();
类型化DataSet的弱点
要修改字段就要重新配置生成
关于类型化DataSet的空值处理
如果某行某列为空值,通过属性获取此行此列的值时会报异常,故而在获取之前应当先判断是否为空。
if(数据Row.is列名Null())
{
空
}
else
{
……
}
添加自定义方法
步骤一:打开.xsd(类型化DataSet设计器)
步骤二:右键->添加->Query->使用SQL语句->选择要生成的查询类型->填写正确的SQL语句->给方法起名->完成
步骤三:调用:adapter.方法名();