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="E:\Visual Studio 2010\WebSites\sql\App_Data\Student.mdf";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="E:\Visual Studio 2010\WebSites\sql\App_Data\Student.mdf";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" /> < >
<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;
}
}
}