zoukankan      html  css  js  c++  java
  • 使用SqlDataAdapter时,需要注意的几点(转)

    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;";

    SqlConnection cn=new SqlConnection(strConn);

    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中缓存的数据!

  • 相关阅读:
    Power BI 根据用户权限动态生成导航跳转目标
    Power BI Tooltips 增强功能
    Power BI refresh error “could not load file or assembly…provided impersonation level is invalid”
    SQL 错误代码 18456
    如何使用SQL Server Integration Services从多个Excel文件读取数据
    通过表格编辑器将现有表引入Power BI数据流
    Power BI 中动态增长的柱状图
    ambari2.7.3离线安装hdp3.1.0时,ambari-hdp-1.repo中baseurl无值
    ambari 安装 cannot download file mysql-connector-java from http://8080/resource/mysql-connector-java.jar
    洛谷P4180 [BJWC2010]严格次小生成树
  • 原文地址:https://www.cnblogs.com/liu-blog/p/3490491.html
Copyright © 2011-2022 走看看