使用SqlDataAdapter时,需要注意的几点
来源:互联网 发布:程序员做笔记的软件 编辑:程序博客网 时间:2024/04/29 10:17
1、SqlDataAdapter内部通过SqlDataReader获取数据,而默认情况下SqlDataReader不能获知其查询语句对应的数据库表名,所以下面的代码:
string strConn,strSQL;
strConn=@"Data Source=.\SQLEXPRESS;"+"Initial Catalog=Northwind;Integrated Security=True;";
strSql="SELECT CustomerID,CompanyName FROM Customers";
SqlDataAdapter da=new SqlDataAdapter(strSQL,strConn);
DataSet ds=new DataSet();
da.Fill(ds);
会在DataSet中创建一个新的DataTable,这个新的DataTable会拥有名为CustomerID和CompanyName 列,但是DataTable对象的名称是Table,而不是我们希望的Customers。
这个问题,可以通过添加TableMapping来解决:
string strConn,strSQL;
strConn=@"Data Source=.\SQLEXPRESS;"+"Initial Catalog=Northwind;Integrated Security=True;";
strSql="SELECT CustomerID,CompanyName FROM Customers";
SqlDataAdapter da=new SqlDataAdapter(strSQL,strConn);
da.TableMappings.Add("Table","Customers");
DataSet ds=new DataSet();
da.Fill(ds);
其实最简洁的方法是通过使用Fill方法的重载,通过指定DataTable,像这样:
SqlDataAdapter.Fill(DataSet,"MyTableName");
这样就可以不必使用TableMappings集合。
2、在使用Fill方式时,可以指定DataTable,而不是DataSet:
string strConn,strSQL;
strConn=@"Data Source=.\SQLEXPRESS;"+"Initial Catalog=Northwind;Integrated Security=True;";
strSql="SELECT CustomerID,CompanyName FROM Customers";
SqlDataAdapter da=new SqlDataAdapter(strSQL,strConn);
DataTable tbl=new DataTable();
da.Fill(tbl);
3、注意打开和关闭连接的处理
在调用SqlCommand对象执行sql命令之前,需要保证与该对象关联的SqlConnection对象时打开的,否则SqlCommand的方法执行时将引发一个异常,但是我们在上面的代码中看到,SqlDataAdapter没有这样的要求。
如果调用SqlDataAdapter的Fill方法,并且其SelectCommand属性的SqlConnection是关闭状态,则SqlDataAdapter会自动打开它,然后提交查询,获取结果,最后关闭连接。如果在调用Fill方法前,SqlConnection是打开的,则查询执行完毕后,SqlConnection还将是打开的,也就是说SqlDataAdapter会保证SqlConnection的状态恢复到原来的情形。
这有时会导致性能问题,需要注意,例如下面的代码:
string strConn,strSQL;
strConn=@"Data Source=.\SQLEXPRESS;"+"Initial Catalog=Northwind;Integrated Security=True;";
SqlDataAdapter daCustomers,daOrders;
strSql="SELECT CustomerID,CompanyName FROM Customers";
daCustomers=new SqlDataAdapter(strSql,cn);
strSql="SELECT OrderID,CustomerID,OrderDate FROM Orders";
daOrders=new SqlDataAdapter(strSql,cn);
DataSet ds=new DataSet();
daCustomers.Fill(ds,"Customers");
daOrders.Fill(ds,"Orders");
以上代码会导致连接被打开和关闭两次,在调用Fill方法时各一次。为了避免打开和关闭SqlConnection对象,在调用SqlDataAdapter对象的Fill方法之前,我们可以先打开SqlConnection对象,如果希望之后关闭连接,我们可以再调用Close方法,就像这样:
cn.Open();
daCustomers.Fill(ds,"Customers");
daOrders.Fill(ds,"Orders");
cn.Close();
4、多次调用Fill方法需要注意数据重复和有效更新数据的问题
string strConn,strSQL;
strConn=@"Data Source=.\SQLEXPRESS;"+"Initial Catalog=Northwind;Integrated Security=True;";
strSql="SELECT CustomerID,CompanyName FROM Customers";
SqlDataAdapter da=new SqlDataAdapter(strSQL,strConn);
DataSet ds=new DataSet();
da.Fill(ds,"Customers");
…….
da.Fill(ds,"Customers");
我们分析上面的代码,通过两次调用Fill方法,SqlDataAdapter执行两次查询,并两次将查询结果保存到DataSet中,第一次调用在DataSet中创建了一个名为Customers的新表。第二次调用Fill方法将查询的结果追加到DataSet中的同一个表中,因此,每个客户的信息将在DataSet中出现两次!当然,如果数据库管理员对Customers表定义了主键,则SqlDataAdapter在天成DataTable时,会判断重复行,并自动丢弃掉旧的值。
考虑一下,假定一个特定客户在第一次调用Fill方法时,存储于数据库中,那么SqlDataAdapter会将其添加到新建的DataTable中。如果后来这个客户被删除了,那么第二次调用Fill方法时,SqlDataAdapter将不会在查询结果中找到该客户信息,但是它也不会将客户信息从DataSet中删除。这就导致了数据更新的问题。
所以推荐的做法是,在调用Fill方法前,先删除本地DataSet中缓存的数据!
- 使用SqlDataAdapter时,需要注意的几点
- switch使用需要注意的几点
- 总结在使用JPA时需要注意的几点
- flume使用hdfs sink时需要注意的几点
- ATL/WTL使用的几点需要注意的地方
- 使用switch语句需要注意的几点
- 使用php apc模块需要注意的几点
- foreach语句使用需要注意的几点
- 关于mysql索引使用需要注意的几点
- 使用TransmitFile函数需要注意的几点
- 使用TransmitFile函数需要注意的几点
- 32位系统使用mongodb需要注意的几点
- strcpy的需要注意的几点
- input标签写CSS时需要注意的几点
- 独立安装LAMP时需要注意的几点
- input标签写CSS时需要注意的几点
- input标签写CSS时需要注意的几点
- Java基本语法学习时需要注意的几点
- 表格隔行变色功能(原生JS和jequery 代码)
- android Camera拍照
- POJ 2236 Wireless Network ||POJ 1703 Find them, Catch them 并查集
- nginx入门
- 在Mac下使用Gitolite来配置git服务
- 使用SqlDataAdapter时,需要注意的几点
- Codeforces Round #244 (Div. 2) E. Police Patrol
- HDU 4586 Play the Dice
- FlashBuilder4的小技巧 代码自动完成 和 代码自动提示
- Android中popWindow弹出菜单的编写
- hdu 1175 连连看
- asdf
- 二层广播(帧广播)和三层广播(路由器广播)有什么区别?
- The specified JRE installation does not exist--TomCat 错误解决