个人学习笔记。
SqlDataReader 是一种不稳定的查询,其查询结果并不会放到本地,只是类似指针那样不断访问服务器中的数据。这样的好处是无论查询结果有多少,对程序占用的内存几乎没有影响;而坏处就是如果本地与服务器的连接中断,数据就无法继续读出。
在 ADO.NET 中提供了一种与服务器连接无关的查询,其会将查询结果存入本地内存当中,这就是 DataSet,它的优缺点与 SqlDataReader 正好相反。
使用 DataSet
DataSet dataSet = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter(sqlCommand);
adapter.Fill(dataSet);
其中,数据集 DataSet 中包含了若干的数据表 DataTable,而 DataTable 中又包含了若干数据行 DataRow。
可以使用 foreach 来遍历:
foreach(DataRow dataRow in dataSet.Tables[0].Rows)
{
// 输出等操作
}
更新 DataSet
一般情况下,对 DataSet 的任何操作,如:删除行 dataTable.Rows.Remove()、增加行 dataTable.NewRow(),这些操作都只会改变内存中的 DataSet,而不会影响到数据库中的数据。
此时,可以使用 SqlDataAdapter 的 Update() 方法将更改更新到数据库中,Update() 可以提交 DataSet、DataTable 和若干 DataRow;需要向 SqlDataAdapter 提供 InsertCommand、DeleteCommand 或 UpdateCommand 才能完成这个过程,但这几个指令的格式非常苛刻,所以一般使用 SqlCommandBuilder 自动生成,如:new SqlCommandBuilder(adapter),此时表中需有主键。
在更新数据库内容后,使用 DataSet 的 GetChanges() 得到新的结果集,以降低传递的资源占用。
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.Update(dataSet);
弱类型 DataSet 的缺点
需要程序员记忆列名以完成 row["<column_name>"],遇到字段为 int 类型时还需要手动转化类型等。弱类型 DataSet 会带来如此不便,对与程序员而言是难以忍受的,所以 visual studio 提供了自动生成强类型 DataSet 的方法。
利用 visual studio 生成并使用强类型 DataSet
在解决方案中添加数据集,然后将表(表中必须有主键!!!)拖入。
拖入后效果图如下:
有些人的 visual studio 会自动生成 app.config 文件,我的没有生成,但不影响结果,目前考虑可能和 visual studio 版本有关。
Connection 中设置连接的数据库,默认会设置好,有需要可手动更改。
然后就到了使用环节,代码如下:
T_PersonsTableAdapter adapter = new T_PersonsTableAdapter();
ConsoleApp0408.DataSetPersons.T_PersonsDataTable persons = adapter.GetData();
for (int i = 0; i < persons.Count; ++i)
{
ConsoleApp0408.DataSetPersons.T_PersonsRow person = persons[i];
string message = string.Format("Name:{0}, Age:{1}, Address:{2}", person.name, person.age, person.address);
Console.WriteLine(message);
}
通过以上代码即可遍历表 T_Persons 的全部数据,如代码所示,可读性得到大幅度提升,且不需要写连接数据库等代码,直接放到 main 里运行即可。
可能有小伙伴像我一样出现如下错误:
这个错误的原因在于给 SqlConnection类的实例提供了错误的连接字符串,通过 Ctrl+F 搜索 ConnectionString 找到:
这个是系统自动生成的代码,这里提供的连接字符串与我数据库属性中的不同,故替换。
也可以改为下述代码:
this._connection.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["****ConnectionString"].ConnectionString;
**** 是数据库名称,例如数据库叫 DB.mdf 则 **** 是 DB。
更改完毕,可以运行。
此时如果想修改表中内容,也变得非常方便:
增
adapter.Insert("name", 99, "address");
删
adapter.Delete(...);
该方法需要输入要删除数据的主键,因为一般情况主键是自增的,所以这个方法很麻烦,建议根据自己情况写一个删除······
改
persons[0].address = "QWE";
adapter.Update(persons[0]);
Update 可以接受行,也可以接受表,即整行修改、整表修改。
如果想要添加新的 SQL 语句,则在图1中右键 Adapter 选择添加查询,整个过程按照说明即可。