6.1  ADO.NET概述

.NET Framework带有自己的数据访问技术ADO.NET。ADO.NET由托管类组成,这些托管类允许.NET应用程序通过这些类连接到数据源,执行命令以及管理非连接的数据。


ADO.NET将数据访问与数据处理分离主要通过两个主要的组件Data Provider和DataSet来完成操作。

6.1.1 Data Provider

数据提供程序是一组用于访问特定数据库,执行SQL命令并获取值的ADO.NET类。就本质而言,数据提供程序是应用程序和数据源之间的一座桥梁。
组成数据提供程序的类包括以下几个:
Connection,提供到数据源的连接。
Command,用于执行SQL命令和存储过程。
DataReader,提供对查询结果的快速的只读、只进访问。
DataAdapter,可以执行两项任务,一是把从数据源获得的信息填充到DataSet,二是依照DataSet的修改更新数据源。

6.1.2 DataSet

DataSet 是专门为独立于任何数据源的数据访问而设计的。因此,它可以用于多种不同的数据源,用于 XML 数据,或用于管理应用程序本地的数据。


DataSet 包含一个或多个 DataTable 对象的集合,这些对象由数据行和数据列以及有关 DataTable 对象中数据的主键、外键、约束和关系信息组成。

 

6.1.3 ADO.NET数据库的访问流程

 ⑴ 基于连接的

①创建Connection对象,建立数据库连接;


②使用Command对象向数据库发送查询(或新增、修改和删除)命令,获取查询结果DataReader对象。


③使用DataReader对象,单向获取数据;


④关闭连接。

 

⑵ 非连接数据访问

 

①创建Connection对象,建立数据库连接;
②创建Command对象,用以向数据库发送查询(或新增、修改和删除)命令;
③创建DataAdapter对象,从数据库中取得数据;
④创建DataSet对象(或DataTable对象),使用DataAdapter对象将数据填充到DataSet对象(或DataTable对象)中;
⑤如果需要,可以重复操作,一个DataSet对象可以容纳多个数据集合;
⑥关闭连接;
⑦在DataSet上进行所需的操作,使用或管理数据。

6.2 ADO.NET的基本命名空间

针对不同的数据源,ADO.NET提供了不同的数据提供程序,但连接数据源的过程具有类似的方式,可以使用几乎同样的代码来完成数据源连接。数据提供程序类都继承自相同的基类,实现同样的接口和包含相同的方法和属性。

.NET有4个数据提供程序:
SQL Server 的数据提供程序:提供对 Microsoft SQL Server 7.0 或更高版本中数据的访问。
OLE DB 的数据提供程序:提供对有OLE DB驱动的数据源的访问。
ODBC 的数据提供程序:提供对有ODBC 驱动的数据源的访问。
Oracle 的数据提供程序:提供对 Oracle 数据源的访问。自.NET4.0开始,此提供程序被废弃,虽仍可使用,但微软推荐使用第三方的提供程序。

 

                                                          ADO.NET命名空间

 

ADO.NET包含许多类,无论是使用SQL Server类,还是使用Oracle类,都可以使用它们。

 

6.3 连接数据库

 

6.3.1 创建SQL Server 2008R2数据库

 

例1:使用SQL Server Management Studio建LibraryManage数据库,并定义UserInfo表

 

① 新建LibraryManage数据库,设定数据库文件的路径

② 新建UserInfo表,定义列,设定主键

 

③ 设定UserId列为自动增长列

 

 

6.3.2 分离与附加数据库

 

可以分离数据库的数据和事务日志文件,然后将它们重新附加到同一或其他 SQL Server 实例。如果要将数据库更改到同一计算机的不同 SQL Server 实例或要移动数据库,分离和附加数据库会很有用。

例:分离LibraryManage数据库

 

例:附加项目文件夹中的LibraryManage数据库

 

 

6.3.3 在Visual Studio 2010中管理数据库

⑴ 使用VS2010建数据库

 

 

 

 

 

 


6.3.4 SqlConnection对象

 

 SqlConnection类用于和要交互的SQL Server数据库建立连接

⑴ 连接字符串

创建SqlConnection对象时,需要提供连接字符串。连接字符串是用分号(;)分隔的一系列名称/值对的选项。这些选项的顺序、大小写并不重要,组合后它们提供了创建连接所需的基本信息。

 

 

连接字符串例:

①连接到本地默认实例
string connectionString="Data Sourse=.; Initial Catalog= Northwind; Integrated Security=true";


②连接到命名实例
string connectionString="Data Source=.\\SqlExpress; Initial Catalog= LibraryManage; Integrated Security=SSPI";

 ③使用用户名和密码连接
string connectionString=@"Data Source=.\SqlExpress; Initial Catalog= LibraryManage; "+ "User ID=sa; PassWord=sxx123";

 

④连接用户实例(User Instance )
每台数据库服务器保存一份已经安装的数据库的主目录。这份列表包括每个数据库的名称以及保存数据的文件位置。连接到数据库时,在连接字符串里通过Initial Catalog指定数据库名称。


SQL Server Express有一个很方便的功能,它可以忽略主列表而直接连接到任何数据库文件,甚至文件不在数据库的主列表里也可以,这项功能叫做User Instance。完整版的SQL Server没有提供这个功能。

为了连接到用户实例,需把User Instance设置为true,并通过AttachDBFileName值指定要连接的数据库文件名,不需要指定Initial Catalog值。


文件名需带上文件的路径,如果以“|DataDirectory|”开头,则自动指向Web应用程序目录的App_Data目录。


string connectionString=@"Data Source=.\SqlExpress; Integrated Security=true;" + @"AttachDBFileName=|DataDirectory|\ LibraryManage.mdf; User Instance=true";

⑵ 连接数据库

① 直接建立连接字串
例:采用直接建立连接字串实现Student数据库连接。

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_4_1.aspx.cs" Inherits="W6_3_4_1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <p> 
          <asp:Label ID="lblText" runat="server" Text="Label"></asp:Label> </p>
    </div>
    </form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.Common;
using System.Data;
using System.Data.SqlClient;
using System.Data.Sql;
using System.Data.Odbc;
using System.Data.SqlTypes;

public partial class W6_3_4_1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string connectionString = @"Data Source=.;Initial Catalog=Student;Integrated Security=true";
        SqlConnection conn = new SqlConnection(connectionString);
 
        try
        {
            conn.Open();
            Label1.Text = "连接已" + conn.State.ToString();
        } catch (Exception err)
        {
            Label1.Text = "连接数据库失败!";
            Label1.Text += err.Message;
        } finally
        {
            conn.Close();
            Label1.Text += "<br />连接已" + conn.State.ToString();
        }
    }
}

结果如下:

② 将连接字符串存放在Web.config文件中


可以在Web.config文件中保存用于连接数据库的连接字符串,使用System.Web.Configuration包中的静态类WebConfigurationManager来获取配置文件中存储的数据库连接信息。

 在<configuration>节中添加<connectionStrings>配置节:
 

<connectionStrings>
    <add name="StudentConnectionString"
     connectionString="Data Source=.; Initial Catalog=Student; Integrated Security=True"
      providerName="System.Data.SqlClient" />
</connectionStrings>

例:获取配置文件中的连接字串,创建数据库连接

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_4_2.aspx.cs" Inherits="W6_3_4_2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
      <p>
          <asp:Label ID="lblText" runat="server" Text="Label"></asp:Label></p>
    </div>
    </form>
</body>
</html>

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Management;
using System.Web.Configuration;
using System.Data.SqlClient;
public partial class W6_3_4_2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

        string connectionString = WebConfigurationManager.ConnectionStrings["StudentConnectionString"].ConnectionString;
        SqlConnection conn = new SqlConnection(connectionString);

        try
        {
            conn.Open();
            lblText.Text = "连接已" + conn.State.ToString();
        }
        catch (Exception err)
        {
            lblText.Text = "连接数据库失败!";
            lblText.Text += err.Message;
        }
        finally
        {
            if (conn != null) conn.Close();
            lblText.Text += "<br />连接已" + conn.State.ToString();
        }

    }
}

③使用using自动清除连接释放对象
using语句声明正在短期使用一个可释放的对象。using语句一旦结束,CLR会立即通过调用对象的Dispose()方法释放相应的对象。

例:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_4_3.aspx.cs" Inherits="W6_3_4_3" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <p> 
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>  </p>
    </div>
    </form>
</body>
</html>

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
using System.Data.SqlClient;

public partial class W6_3_4_3 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string connectionString = WebConfigurationManager.ConnectionStrings["StudentConnectionString"].ConnectionString;
        SqlConnection conn;
        using (conn = new SqlConnection(connectionString)) {
            conn.Open();
            Label1.Text = "连接已" + conn.State.ToString();
        }
        Label1.Text += "<br />连接已" + conn.State.ToString();        
        
        
        
        
    }
}

④自动将数据库连接信息添加到配置文件
通过在页面中添加数据源控件(SqlDataSourse),并配置数据源,可将自动将数据库连接信息添加到配置文件。

 

 

 

<?xml version="1.0"?>

<!--
  有关如何配置 ASP.NET 应用程序的详细信息,请访问
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>

    <connectionStrings>
        <add name="StudentConnectionString" connectionString="Data Source=.;AttachDbFilename=&quot;E:\Visual Studio 2010\WebSites\sql\App_Data\Student.mdf&quot;;Integrated Security=True;Connect Timeout=30;User Instance=True"
            providerName="System.Data.SqlClient" />
    </connectionStrings>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
  <!--
    <connectionStrings>
        <add name="StudentConnectionString" connectionString="Data Source=.; Initial Catalog=Student; Integrated Security=True"
            providerName="System.Data.SqlClient" />
        <add name="StudentConnectionString2" connectionString="Data Source=.;Initial Catalog=STUDENT;Integrated Security=True"
            providerName="System.Data.SqlClient" />
        <add name="StudentConnectionString3" connectionString="Data Source=.;AttachDbFilename=|DataDirectory|\Student.mdf;Integrated Security=True"
            providerName="System.Data.SqlClient" />
        <add name="StudentConnectionString4" connectionString="Data Source=.;AttachDbFilename=|DataDirectory|\Student.mdf;User Instance=true"
            providerName="System.Data.SqlClient" />
        <add name="StudentConnectionString5" connectionString="Data Source=.;AttachDbFilename=&quot;E:\Visual Studio 2010\WebSites\sql\App_Data\Student.mdf&quot;;Integrated Security=True;Connect Timeout=30;User Instance=True"
            providerName="System.Data.SqlClient" />
    
    </connectionStrings>
    
    -->
  
  
</configuration>

 

6.3.5 SqlCommand对象

建立数据库连接之后,就可以执行数据访问和操纵操作了。
一般对数据库的操作被概括为CRUD,即Create、Read、Update和Delete。在ADO.NET中定义SqlCommand对象去执行这些操作。

⑴ SqlCommand类的属性和方法

SqlCommand类的属性包含对数据库执行命令所需要的全部信息。

 

 

⑵ 创建SqlCommand对象

SqlCommand对象的主要构造函数如下:
SqlCommand()
SqlCommand(cmdText)
SqlCommand(cmdText, connection)

⑶ 通过SqlCommand对象返回单个值

例:查询学生人数

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_5_1.aspx.cs" Inherits="W6_3_5_1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div class="div">
       <p> <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
               ConnectionString="<%$ ConnectionStrings:StudentConnectionString %>" 
               SelectCommand="SELECT * FROM [Course]"></asp:SqlDataSource></p>

      <div class="test">
        <p>学生人数:<asp:TextBox ID="txtCount" runat="server"></asp:TextBox></p>
       <p>
           <asp:Button ID="btnQuery" runat="server" Text="查询" οnclick="btnQuery_Click" /> </p>
      </div>


    </div>
    </form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Web.Configuration;
public partial class W6_3_5_1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void btnQuery_Click(object sender, EventArgs e)
    {

        string connectionString = WebConfigurationManager.ConnectionStrings["StudentConnectionString"].ConnectionString;
        string cmdText = "select count(*) from student";
        //查询语句
        SqlConnection conn;
        using (conn = new SqlConnection(connectionString)) {
            //建立连接
            conn.Open();
            SqlCommand cmd = new SqlCommand(cmdText, conn);
            //查询
            txtCount.Text = cmd.ExecuteScalar().ToString();
            //赋值
        
        }



    }
}

 

⑷ 通过SqlCommand对象执行修改操作

 

例:将学号为200301学生选修的课程号为20740061课程的成绩改为90分。

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_5_2.aspx.cs" Inherits="W6_3_5_2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
      <p>成绩: <asp:TextBox ID="txtScore" runat="server"></asp:TextBox></p>

       <p><asp:Button ID="btnUpdate" runat="server" Text="修改成绩" 
               οnclick="btnUpdate_Click" /></p>
       <p>
           <asp:Label ID="lblUpdate" runat="server" Text=""></asp:Label> </p>
    </div>
    </form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Web.Configuration;
public partial class W6_3_5_2 : System.Web.UI.Page
{
    
      private  string connectionString = WebConfigurationManager.ConnectionStrings["StudentConnectionString"].ConnectionString;
     
      private  SqlConnection conn;
      private string getScore() { 
         string cmdText = "select score from sc where sno = 200301 and cno = 20740061";
        //查询语句

         string scores = null ;

         using (conn = new SqlConnection(connectionString)) {
             conn.Open();
             SqlCommand cmd = new SqlCommand(cmdText, conn);
             scores = cmd.ExecuteScalar().ToString();

         
         }

         return scores;
       
      
      }


    protected void Page_Load(object sender, EventArgs e)
    {
        txtScore.Text = getScore();

    }
    protected void btnUpdate_Click(object sender, EventArgs e)
    {
        string cmdText = "update sc set score=99 where sno=200301 and cno=20740061";
        int n = 0;
        using (conn = new SqlConnection(connectionString)) {
            conn.Open();
            SqlCommand cmd = new SqlCommand(cmdText, conn);
            n = cmd.ExecuteNonQuery();
            if (n == 1)
            {
                lblUpdate.Text = "修改成功";
                txtScore.Text = getScore();
            }
            else
            {
                lblUpdate.Text = "修改失败";
            }
        
        }
    }
}

 

⑸ 在SqlCommand对象的命令中指定参数

 

可以使用包含参数的数据命令或存储过程执行查询和更新等操作。
如:
update sc set grade=90 where sno=@Sno and cno=@Cno;

 

SqlParameter类拥有7个构造函数。
SqlParameterCollection拥有4个重载的Add方法,可以用这些方法来创建SqlParameter对象,并将之追加到集合中,还有一个新的AddWithValue方法,
也可以使用SqlCommand的CreateParameter方法。所以存在多种选择。


SqlParameter param1 = new SqlParameter("@Sno", "200301");


SqlParameter param2 = new SqlParameter("@Cno", SqlDbType.Char, 8);
param2.Value = "20740061";

例:

将学号为200301学生选修的课程号为20740061课程的成绩改为90分,使用包含参数的数据命令。

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_5_3.aspx.cs" Inherits="W6_3_5_3" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <p>
        学号:<asp:TextBox ID="txtSno" runat="server"></asp:TextBox> </p>
        <p> 
            课程号:<asp:TextBox ID="txtCno" runat="server"></asp:TextBox> </p>

     <p>成绩: <asp:TextBox ID="txtScore" runat="server"></asp:TextBox></p>

       <p><asp:Button ID="btnUpdate" runat="server" Text="修改成绩" 
               οnclick="btnUpdate_Click" /> <&nbsp>
               
           <asp:Button ID="btnQuery" runat="server" Text="查询成绩" οnclick="btnQuery_Click" 
               style="height: 21px" />
               
         </p>
       <p>
           <asp:Label ID="lblUpdate" runat="server" Text=""></asp:Label> </p>
    </div>
    </form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Web.Configuration;
using System.Data.SqlTypes;
using System.Data.Sql;
using System.Data.Common;
using System.Data;

public partial class W6_3_5_3 : System.Web.UI.Page
{

    private string connectionString = WebConfigurationManager.ConnectionStrings["StudentConnectionString"].ConnectionString;

    private SqlConnection conn;
    private string getScore()
    {
        string cmdText = "select score from sc where sno = @Sno and cno = @Cno";
        SqlParameter param1 = new SqlParameter("@Sno", txtSno.Text.Trim().ToString());
        SqlParameter param2 = new SqlParameter("@Cno", SqlDbType.Char, 8);
        param2.Value = txtCno.Text.Trim().ToString();

        //查询语句

        string scores = null;

        using (conn = new SqlConnection(connectionString))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(cmdText, conn);
            cmd.Parameters.Add(param1);
            cmd.Parameters.Add(param2);

            scores = cmd.ExecuteScalar().ToString();


        }

        return scores;


    }


    protected void Page_Load(object sender, EventArgs e)
    {
      //  txtScore.Text = getScore();

    }
    protected void btnUpdate_Click(object sender, EventArgs e)
    {
        string cmdText = "update sc set score=100 where sno=@Sno and cno=@Cno";

        string cmdText1 = "instert into (10010,Bob, 男,20190430) values(Sno,Sname, Sex, Dno) from student";

      //  SqlParameter param1 = new SqlParameter("@Sno", "200301");
        SqlParameter param2 = new SqlParameter("@Cno", SqlDbType.Char, 8);

        param2.Value = txtCno.Text.Trim().ToString();
        int n = 0;
        using (conn = new SqlConnection(connectionString))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(cmdText, conn);
            cmd.Parameters.Add(new SqlParameter("@Sno", txtSno.Text.Trim().ToString()));
            cmd.Parameters.Add(param2);
           
            n = cmd.ExecuteNonQuery();
            if (n == 1)
            {
                lblUpdate.Text = "修改成功";
                txtScore.Text = getScore();
            }
            else
            {
                lblUpdate.Text = "修改失败";
            }

        }
    }
    protected void btnQuery_Click(object sender, EventArgs e)
    {
        txtScore.Text = getScore();
    }
}

 

 

6.3.6 SqlDataReader对象

使用SqlDataReader对象能以只读、只进的方式每次读取一条SELECT命令返回的记录,是获取数据最简单的方式。
SqlDataReader是基于连接的,且连接是专有的,当不再需要时应立刻关闭。

⑴ SqlDataReader类的属性和方法

 

 

⑵ 创建SqlDataReader对象

 

SqlDataReader对象不能使用new来创建,通常调用SqlCommand对象的ExecuteReader方法获取返回的SqlDataReader对象。
SqlCommand cmd=new SqlCommand(cmdText,conn);
SqlDataReader dr=cmd.ExecuteReader();

⑶ 遍历SqlDataReader对象的记录

当ExecuteReader方法返回SqlDataReader对象时,当前游标的位置是第一条记录之前,当调用Read方法时,游标后移一行,使此行成为当前行,如SqlDataReader对象中不止一行,返回true。
while(dr.Read())
{
    ...
}

⑷ 访问行中字段的值

有两种方法访问记录中的字段,一种是使用索引,另一种是使用Get方法。
dr["sno"]
dr[0]
dr.GetString(0)

例:利用列表框输出所有学生的信息

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_6_1.aspx.cs" Inherits="W6_3_6_1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <p> 
        <asp:ListBox ID="ListBox1" runat="server"></asp:ListBox>
    </div>
    </form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Web.Configuration;
using System.Data;

public partial class W6_3_6_1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
         string connectionString = WebConfigurationManager.ConnectionStrings["StudentConnectionString"].ConnectionString;

         SqlConnection conn;
         string cmdText = "select * from student";
         using (conn = new SqlConnection(connectionString)) {
             conn.Open();
             SqlCommand cmd = new SqlCommand(cmdText, conn);
             SqlDataReader dr = cmd.ExecuteReader();

             ListBox1.Items.Add("学号 姓名 性别 生日 系号");
             while (dr.Read()) {

                 string str = string.Format("{0} {1} {2} {3} {4}", dr[0],dr[1],dr[2] ,dr[3],dr[4]);
                 ListBox1.Items.Add(str);  
             
             }

             dr.Close();
         }

        
    }
    
}

 

 

例:

将学生信息封装到Student对象中,并添加到List集合,用GridView控件显示学生信息。

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_6_2.aspx.cs" Inherits="W6_3_6_2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <p>  
        <asp:GridView ID="GridView1" runat="server">
        </asp:GridView>
    </p>
    </div>
    </form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;

public partial class W6_3_6_2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {


        string connectionString = WebConfigurationManager.ConnectionStrings["StudentConnectionString"].ConnectionString;
        SqlConnection conn;
        List<Student> Students = new List<Student>();
        string cmdText = "select * from student";
        using (conn = new SqlConnection(connectionString))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(cmdText, conn);
            SqlDataReader dr = cmd.ExecuteReader();


            while (dr.Read())
            {

                Student student = new Student();
                student.Sno = dr["sno"].ToString();
                student.Sname = dr["sname"].ToString();
                student.Sex = dr["sex"].ToString();
                student.Birthday = Convert.ToDateTime(dr["birthday"].ToString());
                student.Dno = dr["dno"].ToString();
                Students.Add(student);

            }
            GridView1.DataSource = Students;
            GridView1.DataBind();

            dr.Close();
        }

        
    }
}

 

6.3.7 填充数据库

DataSet是ADO.NET数据库访问组件的核心,主要用来支持ADO.NET的非连接数据库访问与操纵。
DataSet对象通常和DataAdapter对象配合使用,通过DataAdapter对象向DataSet中填充数据。

⑴ SqlDataAdapter对象

SqlDataAdapter对象(数据适配器对象)可以执行SQL命令以及调用存储过程、传递参数,最重要的是取得数据结果集,在数据库和DataSet对象之间来回传递数据。

 

⑵ DataSet对象

DataSet是从数据源中检索到的数据在内存中的缓存,通常将它看做是数据的容器,常用于在组件间传递数据。
DataSet由一组DataTable组成。
DataSet构造函数:
DataSet();
DataSet("表名");

 

例:用SqlDataAdapter填充DataSet

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_7_1.aspx.cs" Inherits="W6_3_7_1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
     <p> 
         <asp:GridView ID="GridView1" runat="server">
         </asp:GridView>  </p>
    </div>
    </form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;

public partial class W6_3_7_1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

        string connectionString = WebConfigurationManager.ConnectionStrings["StudentConnectionString"].ConnectionString;

        SqlConnection conn;
        string cmdText = "select * from student";
        DataSet ds = new DataSet();

        using (conn = new SqlConnection(connectionString)) {
            conn.Open();
            SqlDataAdapter da = new SqlDataAdapter(cmdText, conn);

            da.Fill(ds);
           // da.Update(ds);
        
        }
        GridView1.DataSource = ds.Tables[0];



        GridView1.DataBind();
    }
   
}

例:使用DataSet中的数据更新数据库

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_8_1.aspx.cs" Inherits="W6_3_8_1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
     <p>  
         <asp:GridView ID="GridView1" runat="server">
         </asp:GridView> </p>
    </div>
    </form>
</body>
</html>

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
using System.Data;
using System.Data.SqlClient;
public partial class W6_3_8_1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string cmdText = "select * from student";
        DataSet ds = SqlHelper.ExecuteDataSet(cmdText);
        
        DataView dv = ds.Tables[0].DefaultView;

        dv.Sort = "dno";
        GridView1.DataSource = dv;
        GridView1.DataBind();

    }
}

6.3.8 SqlHelper数据库通用访问类

微软和一些开源项目提供了SqlHelper数据库操作组件,用于简化你重复的去写那些数据库连接(SqlConnection)、SqlCommand和SqlDataReader等操作。SqlHelper 封装过后通常是只需要给方法传入一些参数如数据库连接字符串,SQL参数等,就可以访问数据库了。

例:按系号升序显示学生信息

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="W6_3_8_1.aspx.cs" Inherits="W6_3_8_1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
     <p>  
         <asp:GridView ID="GridView1" runat="server">
         </asp:GridView> </p>
    </div>
    </form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
using System.Data;
using System.Data.SqlClient;
public partial class W6_3_8_1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string cmdText = "select * from student";
        DataSet ds = SqlHelper.ExecuteDataSet(cmdText);
        
        DataView dv = ds.Tables[0].DefaultView;

        dv.Sort = "dno";
        GridView1.DataSource = dv;
        GridView1.DataBind();

    }
}

6.4 Web系统的三层结构

所谓的三层结构就是将系统的整个业务应用划分为表示层、业务逻辑层和数据访问层,这样有利于系统的开发、维护、部署和扩展。

①数据访问层(DAL - Data Access Layer)
数据访问层又称为DAL层,有时候也称为是 持久层,其功能主要是负责数据库的访问。简单的说法就是实现对数据表的Select(查询),Insert(插入),Update(更新),Delete(删除)等操作。如果要加入ORM的元素,那么就会包括对象和数据表之间的mapping,以及对象实体的持久化。

②业务逻辑层(BLL - Business Logic Layer)
业务逻辑层是系统架构中体现核心价值的部分。它的关注点主要集中在业务规则的制定、业务流程的实现等与业务需求有关的系统设计,也即是说它是与系统所应对的领域(Domain)逻辑有关,很多时候,也将业务逻辑层称为领域层。

③表示层(UIL)
表示层负责直接跟用户进行交互,一般指应用程序的界面,用于数据录入、数据显示等。

 

 

Dep.cs:

namespace SXX.Model
{	
	[Serializable()]
	public class Dep
	{	
		public string Dno { get; set; }
		public string Dname { get; set; }
		public string Tel { get; set; }
	}
}

 DepService:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using SXX.Model;

namespace SXX.DAL
{
    public abstract class DepService
    {

        /// <summary>
        /// 添加Dep
        /// </summary>
        public static bool AddDep(Dep dep)
        {   
            string sql ="INSERT INTO Dep (Dno, Dname, Tel) "
                            +"VALUES (@Dno, @Dname, @Tel)";
            SqlParameter[] cmdParams = new SqlParameter[]{
                new SqlParameter("@Dno", SqlHelper.ToDBValue(dep.Dno)),
                new SqlParameter("@Dname", SqlHelper.ToDBValue(dep.Dname)),
                new SqlParameter("@Tel", SqlHelper.ToDBValue(dep.Tel)),
            };
            
            return (SqlHelper.ExecuteNonQuery(sql, cmdParams)==1);            
        }
        
        /// <summary>
        /// 删除Dep
        /// </summary>
        public static bool DeleteDepByDno(string dno)
        {      
            string sql = "DELETE FROM Dep WHERE Dno = @Dno";
            SqlParameter[] cmdParams = new SqlParameter[]{
                new SqlParameter("@Dno", SqlHelper.ToDBValue(dno))
            };
      
            return (SqlHelper.ExecuteNonQuery(sql, cmdParams)==1);
        }
        
        /// <summary>
        /// 更新Dep
        /// </summary>
        public static bool UpdateDep(Dep dep)
        {            
            string sql ="UPDATE Dep SET Dno = @Dno, Dname = @Dname, Tel = @Tel "
                            +" WHERE Dno = @Dno";                            
            SqlParameter[] cmdParams = new SqlParameter[]{               
                new SqlParameter("@Dno", SqlHelper.ToDBValue(dep.Dno)),
                new SqlParameter("@Dname", SqlHelper.ToDBValue(dep.Dname)),
                new SqlParameter("@Tel", SqlHelper.ToDBValue(dep.Tel)),
            };
            
            return (SqlHelper.ExecuteNonQuery(sql, cmdParams)==1);
        }
        
        /// <summary>
        /// 获取Dep的所有记录
        /// </summary>
        public static List<Dep> GetAllDep()
        {
            string sql = "SELECT * FROM Dep";
            using(SqlDataReader dr = SqlHelper.ExecuteReader(sql))
            {
                return ToModels(dr);   
            }
        }
      
        /// <summary>
        /// 根据Dep的主键获取单条记录
        /// </summary>
        public static Dep GetDepByDno(string dno)
        {
            string sql = "SELECT * FROM Dep WHERE Dno = @Dno";
            SqlParameter[] cmdParams = new SqlParameter[]{
                new SqlParameter("@Dno", SqlHelper.ToDBValue(dno))
            };
            using(SqlDataReader dr = SqlHelper.ExecuteReader(sql, cmdParams))
            {
                return dr.Read()?ToModel(dr):null;
            }
        }
      
      
        /// <summary>
        /// 获取Dep的记录总数
        /// </summary>
        public static int GetTotalCount()
        {
            string sql = "SELECT count(*) FROM Dep";
            return (int)SqlHelper.ExecuteScalar(sql);
        }
      
        /// <summary>
        /// 分页获取Dep的记录
        /// </summary>
        public static List<Dep> GetDepByPage(int minRownum,int maxRownum)
        {
            string sql = "SELECT * FROM(SELECT *,row_number() over(ORDER BY Dno) rownum FROM Dep) t WHERE rownum>=@MinRownum AND rownum<=@MaxRownum";
            SqlParameter[] cmdParams = new SqlParameter[]{new SqlParameter("@MinRownum",minRownum),new SqlParameter("@MaxRownum",maxRownum)};
            using(SqlDataReader dr = SqlHelper.ExecuteReader(sql,cmdParams))
            {
                return ToModels(dr);     
            }
        }
        
        
        ///<summary>
        ///判断Dno是否存在
        ///</summary>
        public static bool IsDnoExist(string dno)
        {
            string sql="SELECT * FROM Dep WHERE Dno=@Dno";
            SqlParameter cmdParam=new SqlParameter("@Dno",SqlHelper.ToDBValue(dno));
            return Convert.ToInt32(SqlHelper.ExecuteScalar(sql,cmdParam))>0;             
        }
        
        
        ///<summary>
        ///判断Dname是否存在    
        ///</summary>
        public static bool IsDnameExist(string dname)
        {
            string sql="SELECT * FROM Dep WHERE Dname=@Dname";
            SqlParameter[] cmdParams = new SqlParameter[]{
                new SqlParameter("@Dname", SqlHelper.ToDBValue(dname)),
            };
            return Convert.ToInt32(SqlHelper.ExecuteScalar(sql,cmdParams))>0;
        }
        ///<summary>
        ///判断Tel是否存在    
        ///</summary>
        public static bool IsTelExist(string tel)
        {
            string sql="SELECT * FROM Dep WHERE Tel=@Tel";
            SqlParameter[] cmdParams = new SqlParameter[]{
                new SqlParameter("@Tel", SqlHelper.ToDBValue(tel)),
            };
            return Convert.ToInt32(SqlHelper.ExecuteScalar(sql,cmdParams))>0;
        }
      
        /// <summary>
        /// 将获取的单条数据转封装成对象返回
        /// </summary>
        private static Dep ToModel(SqlDataReader dr)
        {
            Dep dep = new Dep();
            dep.Dno = (string)SqlHelper.ToModelValue(dr,"Dno");
            dep.Dname = (string)SqlHelper.ToModelValue(dr,"Dname");
            dep.Tel = (string)SqlHelper.ToModelValue(dr,"Tel");
            return dep;
        }

        /// <summary>
        /// 将获取的多条数据转换成对象并添加到泛型集合返回
        /// </summary>
        private static List<Dep> ToModels(SqlDataReader dr)
        {
            var list = new List<Dep>();
            while(dr.Read())
            {
                list.Add(ToModel(dr));
            } 
            return list;
        }
    }
}