图解Ado.net衔接数据库并存取数据的几种方法

首先上两个通用的图:   上面这两个图都是描写Ado.net的作业原理的。 应用程序读取数据共有三种方法: (1)直接通过Command方针读取(但一次只能对一条数据,即表的一行),读完后不断开联接。 (2)通过DataReader方针读取(类似单向管道似的,一条一条的读数据),读完后不断开联接。 (3)通过DataAdapter一次读一堆数据(这个堆就是DataSet),读完后就断开数据库联接了 http://www.fpzhangsha.com 。   应用程序更新和刺进数据共有两种方法: 因为DataReader是单向的,全部不能用于刺进和更新数据,只能从数据库读取数据,所以应用程序更新和刺进数据只需上面的(1)和(3)两者方法。   从Ado.net的作业原理图可以看出,不管用哪种方法和数据库打交道,都有必要有三个的东西:Connection,Command和Sql语句。 第(1)种方法如下图: 图中把工厂比方成数据库,把商城仓库比方成应用程序地址内存,把Command比方成取货员“二愣子”(因为他比较笨),把Sql语句比方成订单,把桥比方成数据库联接方针。 第(1)方法的作业进程就是,首先要j架设好桥,然后二愣子拿到订单(Sql语句)后,就往工厂跑,把订单给工厂管理员,取回订单所需的货品(数据)后,再折回来来把货品放入仓库(内存)。可是因为一自己的力气有限,二愣子来回跑的进程中,一个来回只能搬回一件货品。这时分联接不能断(桥不能拆),因为每次需要取一件货品的时分,二愣子都需要来回跑。 方法(1)的全体形象就是,“二愣子”不断的来回跑。   第(2)种方法的作业进程就是,架设好桥后,二愣子拿着“订单”往工厂跑,但这次的订单比较杂乱,他相当于一份合同,需要和工厂建立一个管道,仓库需要啥货品,直接操作管道的一头的控制按钮,则管道另一头会自动提取需要的货品并通过管道输送到仓库。这样“二愣子”就只需要跑一趟就行了(这份作业轻松、高兴!)。这时分联接也不能断(管道不能断),只需坚持联接才华不断的一件件从工厂取货品并通过管道输送到仓库。 方法(2)的全体形象就是,有一天单向管道。 如下图:   第(3)种方法的作业进程就是,架设好桥后,二愣子拿着“订单”开着车往工厂跑,但这次订单需要的货品比较多,工厂就把这一堆货品帮二愣子装上车,二愣子高高兴兴的开着车兜着风把这一堆货品运回去。这次二愣子不只能兜风,而且也只跑一趟(这份作业真拉风!)。车开回来后就可以断开联接了(彻底可以把桥拆了),因为需要的全部货品都现已通过货车运回来了。此时,货车就比方为DataAdapter方针,DataSet方针就比方成货车拉回来的那“一堆货品的集结”。 方法(3)的全体形象就是,“二愣子”开着货车。 见下图:  另外,网上有一个非常好看点的图(意义和上图一样),如下:   总结:从上面的图可以看出,无论用啥方法取货品都有必要有三个东西参与才华结束:桥,二愣子,订单。即:Connection,Command和Sql语句。实际上在运用DataAdapter的时分可以看不到Command方针,其实DataAdapter也是有必要通过Command方针取货品的,只不过DataAdapter内部自己有Command方针算了,DataAdapter运用自己内部的Command方针(这点从最上面的Ado.net原理图可以看出)。 取货品就是从数据库中取数据,更新和刺进数据到数据库的进程和取数据一样,也需要Connection,Command和Sql语句这三个东西,此不赘述。   详细代码如下: 假定配置文件如下: 

  
    
  

   (1)直接通过Command方针读取(但一次只能对一条数据,即表的一行),读完后不断开联接。 第一步:建立Connection方针(桥) string connectionString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString.ToString(); //从配置文件中取出联接字符串 SqlConnection conn = new SqlConnection(connectionString);        conn.Open();  //翻开联接 第二步:建立SQL语句(订单) string sqlStr=“ Select * from Student where ID='10' ”; 第三步:建立Command方针(二愣子),用这个方针直接回来一个行数据。 SQLCommand cmd=new SQLCommand(sqlStr,conn); //参数就是sql语句和联接方针 //注重通过new Command方针的连个参数把这三个有必要的东西联络在一起了。 下面就是实行Command方针的方法了,共有三种方法: int  LineCount=cmd.ExecuteNonQuery();  //一般用于更新和刺进语句,不回来查询效果,但这个函数的回来值本身回来影响的行数。 DataReader  dr=cmd.ExecuteReader(); //一般用于Select语句回来查询的数据,然后通过DataReader一个个的读取。 int  OneValue=cmd.ExecuteScaler(); //一般用于Select查询,但回来效果为一个值的情况,比方SQL语法中的Count函数和Sum函数。这也印证了二愣子力气有限,仅凭自己的力气一次只能搬回一件货品,或许不搬回货品,仅通知数据库更新和刺进一个数据。 总之,更新和刺进用ExecuteNonQuery,查询首要运用ExecuteReader,特别情况(只回来单个值)才用ExecuteScaler。 结尾别忘了关闭联接,conn.Close();   (2)通过DataReader方针读取(类似单向管道似的,一条一条的读数据),读完后不断开联接。 第一步:建立Connection方针(桥)       string myconn="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind"; SqlConnection conn=new SqlConnection(myconn);         第二步:建立SQL语句(订单) string mysql="select OrderID,CustomerID from Orders where CustomerID='CHOPS'"; 第三步:建立Command方针(二愣子),但用这个方针回来一个管道DataReader   SqlCommand cmd=new(mysql,conn);       conn.Open();  //翻开数据库联接,用之前翻开就行,放在哪无所谓  //通过SqlCommand的ExecuteReader()方法布局DataReader 方针。 SqlDataReader myreader=cmd.ExecuteReader(); while(myreader.read()){   Console.WriteLine(myreader.GetInt32(0) "," myreader.GetString(1)); } myreader.Close(); myconnection.Close(); 补偿:SqlDataReader读数据方法有两大类,带小括号的函数和带中括号的索引特色 带小括号的有,GetInt32(), GetString()等,参数都是int类型,标明列号,也只能运用列号。 带中括号的有,直接带上中括号,有myreader[0] 和 myreader["ID"]两种,即可以运用列号,也可以运用列名。   (3)通过DataAdapter一次读一堆数据(这个堆就是DataSet),读完后就断开数据库联接了。 第一步:建立Connection方针(桥) string connectionString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString.ToString(); //从配置文件中取出联接字符串 SqlConnection conn = new SqlConnection(connectionString);        conn.Open();  //翻开联接 第二步:建立SQL语句(订单) string sqlStr=“ Select * from Student where ID='10' ”; 第三步:建立DataAdapter方针(这个方针内部隐式的建立了Command方针),即建立好货车就行了,货车内部有人。但通过这个方针填充DataSet,DataSet在本地内存中 SqlDataAdapter da=new SqlDataAdapter(sqlStr,conn);  //参数仍然是sql语句和联接方针 DataSet ds=new DataSet(); ds.Fill(ds,"表名");   运用参数的Sql语句,即运用Paramerter方针比方如下: 这里运用SqlParamerter方针,这个方针是SqlParamerters集结的子元素,每个Command方针都有一个Parameters特色。【就如同二愣子不只拿着订单,还拿着订单中每样货品对应的更详细的货品描写的表单。】 下面代码目的是根据已知的名字和暗码获取年岁大小。 string name = "Tim"; string pwd ="123456"; string Age; string constr = @"server=.\sqlexpress;database=MyDataBase;uid=sa;pwd=sa"; using (SqlConnection sqlconn = new SqlConnection(constr))  //第一步,建立联接方针 {          //参数化查询1         string cmdstr = @"select age from loginn where uname=@name1 and upwd=@pwd1";          //第二步,建立Sql语句。 @name1,@pwd1仅仅是别号算了,相当于局部变量         using (SqlCommand cmd =new SqlCommand(cmdstr, sqlconn))   //第三步,建立Command方针                 {                         //加参数                        cmd.Parameters.Add(new SqlParameter("@name1", name));                         //把name中的值赋给@name                        cmd.Parameters.Add(new SqlParameter("@pwd1", pwd));//注重Add方法中是new了一个 SqlParameter                        // cmd.Parameters.AddWithValue("@pwd1", pwd);//此方法内部完结同Add,举荐用前者                        if (sqlconn.State == ConnectionState.Closed)                                {                                         sqlconn.Open();                                         Age=cmd.ExecuteScalar();    //获取年岁                                        //由所以查询且age字段是int类型,且Sql语句回来一个单值,所以用ExecuteScalar最便当。 否则就需要用ExecuteReader。                                        }  //end if                              }  //end using }  //end using     运用存储进程的比方如下: 转自:http://www.cnblogs.com/herbert/archive/2010/07/12/1775889.html ADO.NET中调用存储进程 下面这个比方展示如安在ADO.NET调用存储进程。我只选择了一种方法,说实话不太喜欢多样化的方法去处理问题,这种发散式的做法在编程中如同没有必要。选择自己喜欢的一种方法。 这里SQL Server有一个样本数据库Northwind. 以Northwind里的Region表为例: Region表有2个字段: RegionID, int 主键 RegionDescription, nchar(50) 写以下几个存储进程: RegionUpdate: 多个参数 CREATE PROCEDURE RegionUpdate(@RegionID INTEGER, @RegionDescription NCHAR(50))
AS
SET NOCOUNT OFF
UPDATE Region
SET RegionDescription = @RegionDescription
WHERE RegionID = @RegionID GO RegionDelete 一个参数 CREATE PROCEDURE RegionUpdate(@RegionID INTEGER)
AS
SET NOCOUNT OFF
DELETE FROM Region
WHERE RegionID = @RegionID
GO
 RegionInsert 带回来参数 CREATE PROCEDURE RegionInsert(@RegionDescription NCHAR(50), @RegionID INTEGER OUTPUT)
AS
SET NOCOUNT OFF
SELECT @RegionID = MAX(RegionID)   1 
FROM Region
INSERT INTO Region VALUES(@RegionID, @RegionDescription)
GO

   工程添加下面的配置文件 App.confi   

  
    
  

 关于联接字符串怎样写参看: http://www.connectionstrings.com 下面是C# code: using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;


namespace SQLProcedureDemo
{
    class Program
    {
        private static string GetConnectionStringsConfig(string connectionName)
        {
            string connectionString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString.ToString();
            Console.WriteLine(connectionString);
            return connectionString;
        }


        static void Main(string[] args)
        {
            string source = GetConnectionStringsConfig("Northwind");

            try
            {
                using (SqlConnection conn = new SqlConnection(source))
                {
                    conn.Open();

                    // Invoke RegionUpdate Procedure
                    SqlCommand cmd = new SqlCommand("RegionUpdate", conn);
                    cmd.CommandType = CommandType.StoredProcedure;
                    SqlParameter updatepara1 = new SqlParameter("@RegionID", SqlDbType.Int);
                    updatepara1.Value = 3;
                    cmd.Parameters.Add(updatepara1);
                    SqlParameter updatepara2 = new SqlParameter("@RegionDescription", SqlDbType.NChar);
                    updatepara2.Value = "Northern";
                    cmd.Parameters.Add(updatepara2);

                    // You can also use the following statement
                    //cmd.Parameters.AddWithValue("@RegionID", 3);
                    //cmd.Parameters.AddWithValue("@RegionDescription", "Northern");

                    cmd.ExecuteNonQuery();

                    // Invoke RegionDelete Procedure                    
                    SqlCommand cmdDel = new SqlCommand("RegionDelete", conn);
                    cmdDel.CommandType = CommandType.StoredProcedure;
                    SqlParameter myParameter = new SqlParameter("@RegionID", SqlDbType.Int);
                    myParameter.Value =5;
                    cmdDel.Parameters.Add(myParameter);
                    cmdDel.ExecuteNonQuery();
                    

                    // Invoke RegionInsert Procedure
                    SqlCommand cmdInsert = new SqlCommand("RegionInsert", conn);
                    cmdInsert.CommandType = CommandType.StoredProcedure;
                    
                    SqlParameter para1 = new SqlParameter("@RegionDescription", SqlDbType.NChar);
                    para1.Value = "South West";
                    cmdInsert.Parameters.Add(para1);

                    SqlParameter para2 = new SqlParameter("@RegionID", SqlDbType.Int);
                    para2.Direction = ParameterDirection.Output;
                    cmdInsert.Parameters.Add(para2);

                    cmdInsert.ExecuteNonQuery();

                    int newRegionID = (int)cmdInsert.Parameters["@RegionID"].Value;
                    Console.WriteLine(newRegionID);                    
                    conn.Close();
                }
            }
            catch (SqlException ex)
            {
                //

                Console.WriteLine(ex.Message);
 
            }

            Console.ReadKey();
        }
    }
}
   http://www.topkp123.com 
posted @ 2013-04-07 05:36  chinadiy197601  阅读(303)  评论(0编辑  收藏  举报