ado.net中的 sqlconnection sqlcommand datareader dataset SqlDataAdapter之间的关系


Connection: 
和数据库交互,必须连接它。连接帮助指明数据库服务器、数据库名字、用户名、密码,和连接数据库所需要的其它参数。Connection对象会被Command对象使用,这样就能够知道是在哪个数据源上面执行命令。 

Command: 

Command对象就是用来执行数据库操作命令的。比如对数据库中数据表的插入,删除,更新等都要通过Command对象来实现的。可以执行查询(SELECT语句),执行插入(INSERT语句),执行更新(UPDATE语句),执行删除(DELETE语句)。这个对象是架构在Connection 对象上,也就是Command 对象是透过连结到数据源。

DataReader: 
当我们只需要循序的读取数据而不需要其它操作时,可以使用DataReader 对象。DataReader对象只是一次一笔向下循序的读取数据源中的数据,而且这些数据是只读的,并不允许作其它的操作。因为DataReader 在读取数据的时候限制了每次只读取一笔,而且只能只读,所以使用起来不但节省资源而且效率很好。使用DataReader 对象除了效率较好之外,因为不用把数据全部传回,故可以降低网络的负载。ADO.NET 使用Connection 对象来连接数据库,使用Command 或DataAdapter对象来执行SQL语句,并将执行的结果返回给DataReader 或 DataAdapter ,然后再使用取得的DataReader 或DataAdapter 对象操作数据结果。

DataAdapter: 
主要是在数据源以及DataSet 之间执行数据传输的工作,它可以透过Command 对象下达命令后,并将取得的数据放入DataSet 对象中。这个对象是架构在Command对象上,并提供了许多配合DataSet 使用的功能。

DataSet:  DataSet对象是ADO.NET的核心,基于DataSet的数据模型才使得ADO.NET实现离线式数据操作模型。可以把从数据库中所查询到的数据保留起来,甚至可以将整个数据库显示出来。DataSet 的能力不只是可以储存多个Table 而已,还可以透过DataAdapter对象取得一些例如主键等的数据表结构,并可以记录数据表间的关联。这个对象架构在DataAdapter对象上,本身不具备和数据源沟通的能力;也就是说我们是将DataAdapter对象当做DataSet 对象以及数据源间传输数据的桥梁。 DataSet是存在于内存中的数据库,是专门用来处理数据保存体中读出的数据。它的优点就是离线式的,一点读取到数据源中的数据后,就在内存中建立数据库的副本,在此之后的操作,直到执行更新命令为止,所有的操作都是在内存中完成的。不管底层的数据库是哪种形式,DataSet的行为都是一致。其中比较常用的列表控件(DataGridView,ComboBox)。

 

 DataReader与DataAdapter和DataSet读取数据的区别

  DataReader:

        public static string strconn = "server=.;database=Test;uid=sa;pwd=123456";
        static void Main(string[] args)
        {
            SqlConnection conn = new SqlConnection(strconn);
            conn.Open();
            SqlCommand comm = new SqlCommand();

            comm.Connection = conn;
            comm.CommandText = "prcPageResult";

            SqlParameter[] prams = {
                new SqlParameter("@currPage", "1"),
                new SqlParameter("@showColumn", "*"),
                new SqlParameter("@tabName", "test"),
                new SqlParameter("@strCondition", ""),
                new SqlParameter("@ascColumn", "ID"),
                new SqlParameter("@bitOrderType", "0"),
                new SqlParameter("@pkColumn", "ID"),
                new SqlParameter("@pageSize", "5")
          };
            int j = 0;
            comm.Parameters.AddRange(prams);
            comm.CommandType = CommandType.StoredProcedure;
            List<testModel> entitylist = new List<testModel>();
            using (SqlDataReader reader = comm.ExecuteReader())
            {

                while (reader.Read())
                {
                    testModel entity = new testModel();
                    entity.ID = Convert.ToInt32(reader["ID"]);
                    entity.Name = reader["Name"].ToString();
                    entitylist.Add(entity);
                }
            }
            for (int i = 0; i < entitylist.Count; i++)
            {
                Console.WriteLine(entitylist[i].Name);
            }

            conn.Close();
            Console.Read();

        }

  DataAdapter和DataSet:

 public static string strconn = "server=.;database=Test;uid=sa;pwd=123456";
        static void Main(string[] args)
        {
            SqlConnection conn = new SqlConnection(strconn);
            conn.Open();
            SqlCommand comm = new SqlCommand();

            comm.Connection = conn;
            comm.CommandText = "prcPageResult";

            SqlParameter[] prams = {
                new SqlParameter("@currPage", "1"),
                new SqlParameter("@showColumn", "*"),
                new SqlParameter("@tabName", "test"),
                new SqlParameter("@strCondition", ""),
                new SqlParameter("@ascColumn", "ID"),
                new SqlParameter("@bitOrderType", "0"),
                new SqlParameter("@pkColumn", "ID"),
                new SqlParameter("@pageSize", "5")
          };
            comm.Parameters.AddRange(prams);
            comm.CommandType = CommandType.StoredProcedure;

            SqlDataAdapter da = new SqlDataAdapter(comm);
            DataSet ds = new DataSet();
            da.Fill(ds, "test");
            List<testModel> entitylist = new List<testModel>();
            
            foreach (DataRow item in ds.Tables[0].Rows)
            {
                testModel entity = new testModel();
                entity.ID = Convert.ToInt32(item["ID"]);
                entity.Name = item["Name"].ToString() ;
                entitylist.Add(entity);
            }
            conn.Close();
            Console.Read();

        }

 

 

SqlDataAdapter概述

  SqlDataAdapter是 DataSet和 SQL Server之间的桥接器,用于检索和保存数据。SqlDataAdapter通过对数据源使用适当的Transact-SQL语句映射 Fill(它可更改DataSet中的数据以匹配数据源中的数据)和 Update(它可更改数据源中的数据以匹配 DataSet中的数据)来提供这一桥接。当SqlDataAdapter填充 DataSet时,它为返回的数据创建必需的表和列(如果这些表和列尚不存在)。

  我们可以通过以下三种方法来创建SqlDataAdapter对象:

  使用方法

  1、通过连接字符串和查询语句

  string strConn="uid=账号;pwd=密码;database=数据库;server=服务器";//SQL Server链接字符串

  strSql="SELECT * FROM 表名";

  SqlDataAdapter da=new SqlDataAdapter(strSql,strConn);

  DataSet ds=new DataSet();//创建DataSet实例

  da.Fill(ds,"自定义虚拟表名");//使用DataAdapter的Fill方法(填充),调用SELECT命令

  这种方法有一个潜在的缺陷。假设应用程序中需要多个SqlDataAdapter对象,用这种方式来创建的话,会导致创建每个SqlDataAdapter时,都同时创建一个新的SqlConnection对象,方法二可以解决这个问题

  2、通过查询语句和SqlConnection对象来创建

  string strConn="uid=账号;pwd=密码;database=数据库;server=服务器";//SQL Server链接字符串

  SqlConnection conn=new SqlConnection(strConn);

  string strSql="SELECT * FROM 表名";

  SqlDataAdapter da = new SqlDataAdapter(strSql, conn);

  DataSet ds=new DataSet();//创建DataSet实例

  da.Fill(ds,"自定义虚拟表名");//使用DataAdapter的Fill方法(填充),调用SELECT命令

  3、通过SqlCommand对象来创建

  string strConn="uid=账号;pwd=密码;database=数据库;server=服务器";//SQL Server链接字符串

  SqlConnection connSql=new SqlConnection (strConn); //Sql链接类的实例化

  connSql.Open ();//打开数据库

  //使用SqlDataAdapter时没有必要从Connection.open()打开,

  //SqlDataAdapter会自动打开关闭它。

  string strSql = "SELECT * FROM 表名"; //要执行的SQL语句

  SqlCommand cmd=new SqlCommand(strSql,connsql);

  SqlDataAdapter da=new SqlDataAdapter(cmd); //创建DataAdapter数据适配器实例

  DataSet ds=new DataSet();//创建DataSet实例

  da.Fill(ds,"自定义虚拟表名");//使用DataAdapter的Fill方法(填充),调用SELECT命令

  ConnSql.Close ();//关闭数据库

  SqlDataAdapter da=new SqlDataAdapter(strSQL,ConnSql); //创建DataAdapter数据适配器实例DataSet ds=new DataSet();//创建DataSet实例da.Fill(ds,"自定义虚拟表名");//使用DataAdapter的Fill方法(填充),调用SELECT命令ConnSql.Close ();//关闭数据库

  注意

  如果只需要执行SQL语句或SP,就没必要用到DataAdapter ,直接用SqlCommand的Execute系列方法就可以了。sqlDataadapter的作用是实现Dataset和DB之间的桥梁:比如将对DataSet的修改更新到数据库。

  SqlDataAdapter的UpdateCommand的执行机制是:当调用SqlDataAdapter.Update()时,检查DataSet中的所有行,然后对每一个修改过的Row执行SqlDataAdapter.UpdateCommand ,也就是说如果未修改DataSet中的数据,SqlDataAdapter.UpdateCommand不会执行。

  使用要点

  1、SqlDataAdapter内部通过SqlDataReader获取数据,而默认情况下SqlDataReader不能获知其查询语句对应的数据库表名,

  所以下面的代码:

  string strConn = "uid=账号;pwd=密码;database=数据库;server=服务器";//SQL Server链接字符串

  strSql="SELECT * FROM 表名";

  SqlDataAdapter da = new SqlDataAdapter(strSql,strConn);

  DataSet ds = new DataSet();

  da.Fill(ds);

  会在DataSet中创建一个新的DataTable,这个新的DataTable会拥有名为CustomerID和CompanyName 列,但是DataTable对象的名称是Table,而不是我们希望的Customers。

  这个问题,可以通过添加TableMapping来解决:

  string strConn="uid=账号;pwd=密码;database=数据库;server=服务器";//SQL Server链接字符串

  strSql="SELECT * FROM 表名";

  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="uid=账号;pwd=密码;database=数据库;server=服务器";//SQL Server链接字符串

  strSql="SELECT * FROM 表名";

  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="uid=账号;pwd=密码;database=数据库;server=服务器";//SQL Server链接字符串

  SqlConnection conn=new SqlConnection(strConn);

  SqlDataAdapter daCustomers,daOrders;

  strSql="SELECT * FROM Customers";

  daCustomers = new SqlDataAdapter(strSql, conn);

  strSql="SELECT * FROM Orders";

  daOrders=new SqlDataAdapter(strSql, conn);

  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="uid=账号;pwd=密码;database=数据库;server=服务器";//SQL Server链接字符串

  strSql="SELECT * 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中缓存的数据!

 

 转自:http://blog.csdn.net/chelen_jak/article/details/46821817

 

 

ADO种的增删改查

  新增:

  SqlConnection conn= new SqlConnection(connectionStr);            //建立连接
  conn.Open();                                                      //打开数据库连接
  string sqlStr = "(SQL执行语句,例如  insert into A  values('abc',1))";    //定义相关的执行语句,相当于写好命令
  SqlCommand command1 = new SqlCommand(sqlStr, conn);          //构造函数指定命令对象所使用的连接对象connection1以及命令文本sqlStr ,相当于让系统接受命令。
  command1.ExecuteNonQuery();                                   //ExecuteNonQuery()方法返回值受影响的记录条数为一整数,代表操作所影响到的行数,注意ExecuteNonQuery()方法一般用于执行 UPDATE、INSERT、DELETE等非查询语句                                                                                                            // UPDATE、INSERT、DELETE等非查询语句,可以理解为让系统执行命令
  conn.Close();     ///关闭数据库连接

  修改:

string connectionStr = "Data source=.;Initial Catalog=Student; Integrated Security=True";
SqlConnection connection = new SqlConnection(connectionStr);
string sqlStr = "update Course set Ccredit=5 where Cname='线性代数'";
SqlCommand command1= new SqlCommand(sqlStr, connection);
connection .Open();
if (command1.ExecuteNonQuery() > 0)
{
MessageBox.Show("学分修改成功!");
};
connection .Close();

  删除:

string connectionStr = "Data source=.;Initial Catalog=Student; Integrated Security=True";
SqlConnection connection = new SqlConnection(connectionStr);
string sqlStr = "DELETE FROM Person WHERE LastName = 'Wilson' ";
SqlCommand command1
= new SqlCommand(sqlStr, connection);
connection .Open();

if (command1.ExecuteNonQuery() > 0)
{
  MessageBox.Show(
"删除成功!");
};
connection .Close();

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com