6/29 原型编码阶段:(1)连接并访问数据库

打开VS2005的CAROA项目,第一个程序我就想做员工列表页面。以便熟悉和了解asp.net2.0中对数据库的操作和显示方法。

我的目的很明确,就是实现员工管理功能第一阶段要求:
列出所有部门(下拉列表)
选择部门列出相应员工(GridView,级联)
选择员工显示员工详细信息(DetailsView)
增加新部门(部门存在上下级关系)
修改部门名称
删除部门(该部门下必须没有员工)
增加新员工
修改员工信息
删除员工

1.首先进行数据库设计和范例数据的填充:
表Clerk

字段名 类型 说明
ClerkID int 主键
RealName nvarchar() 员工姓名
JobNum nvarchar() 员工工号
DeptID int 部门编号
数据有陈公客,王公客,张大客,李大客。分属相关的部门。

表CODE_Dept
字段名 类型 说明
DeptID int 主键
DeptName nvarchar() 部门名称
ParentDeptID int 上级部门
AreaID int 地区编号
数据有公客部,市场部,大客部三条。都属于南京分公司。

表CODE_Area
字段名 类型 说明
AreaID int 主键
AreaName nvarchar() 地区名称
数据有南京,北京二条。
在数据库关系图中,我们将Code_Area,Code_Dept,Clerk关联起来。

在表里面添加示例数据后,按照我们设定的目标开始进行编码!

2.怎样读取web.config中的数据库连接字串:
web.config中的数据库连接字串部分:

<configuration>
 
<appSettings/>
 
<connectionStrings>
  
<add name="CAROAConnectionString" connectionString="Data Source=192.xx.xx.xx;Initial Catalog=CAROA;Persist Security Info=True;User ID=xxx;Password=xxx" providerName="System.Data.SqlClient"/>
 
</connectionStrings>
.....

</configuration>


在DAL.cs数据访问层中读取如下(注DAL.cs是数据访问层的代码,主要用于完成最底层的数据库操作,来源于Microsoft Data Access Application Block for .NET):
public static readonly string CONN_STRING = System.Configuration.ConfigurationManager.ConnectionStrings["CAROAConnectionString"].ConnectionString;

在表示层ClerkList.aspx的SqlDataSource中读取如下:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:CAROAConnectionString %>"
            SelectCommand
="SELECT * FROM [Clerk]"></asp:SqlDataSource>

使用Web.Configuration而非System.Configuration时代码如下:
using System.Web.Configuration;

ConnectingStringSettings conn_string 
= WebConfigurationManager.ConnectionStrings["CAROAConnectionString"];

或者

string conn_string = WebConfigurationManager.ConnectionStrings["CAROAConnectionString"].ConnectionString;

当然 如果要在项目中加密数据库连接字符串,可以这么做
D:\Program Files\Microsoft Visual Studio 8\VC>aspnet_regiis -pe "connectionStrin
gs" -app "/CarOAWeb" -prov "RSAProtectedConfigurationProvider"
或者这么写
aspnet_regiis -pe "connectinStrings" -app "/CarOAWeb"

解密只需 将-pe 改成 -pd即可
前提是 项目站点使用IIS,并且为网站配置了虚拟目录

否则会出现我这样的出错信息:
正在加密配置节
打不开虚拟路径“
/CarOAWeb”和站点“默认网站”的配置。
指定的参数已超出有效值的范围。
参数名: site
失败
!

在ASP.NET 1.1中,我们一般是把连接字串写在<appSetting>之中,如下:
<configuration>
 
<appSettings/>
  
<add key="CAROAConnectionString" value="Data Source=192.xx.xx.xx;Initial Catalog=CAROA;Persist Security Info=True;User ID=xxx;Password=xxx" providerName="System.Data.SqlClient"/>
 
</appSettings>

..
</configuration>

这时,读取设置的语句就是这样了(ASP.NET 2.0):
string conn_string = System.Configuration.ConfigurationManager.AppSettings["CAROAConnectionString"].ToString;

3.接下来打开数据库,执行选取所有员工sql语句
利用ADO.NET,我们是这样编写的:
首先在ClerkList.aspx中拖入一个GridView控件,ID是GridView1。
ClerkList.aspx.cs中代码如下:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class clerklist : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    
{
        
//创建连接字符串
        string conn_string = System.Configuration.ConfigurationManager.ConnectionStrings["CAROAConnectionString"].ConnectionString;
        
//创建命令字符串
        string comm_string = "select * from clerk";
        
//构造SqlDataAdapter对象
        SqlDataAdapter dataAdapter = new SqlDataAdapter(comm_string, conn_string);
        
//创建一个DataSet对象
        DataSet dataSet = new DataSet();
        
//填充DataSet对象
        dataAdapter.Fill(dataSet, "Clerk");
        
//从DataSet中获取DataTable
        DataTable dataTable = dataSet.Tables["Clerk"];
        
//将DataTable绑定到GridView
        GridView1.DataSource = dataTable;
        GridView1.DataBind();
    }

}

DataSet虽然很强大,而且是离线数据源,但是需要额外的资源,为了创建更快速的记录集,我们可以用SqlDataReader对象实现相同的效果,但是DataReader相对于DataSet,只能向前。page_load部分的代码如下:
    protected void Page_Load(object sender, EventArgs e)
    
{
        
//创建连接字符串
        string conn_string = System.Configuration.ConfigurationManager.ConnectionStrings["CAROAConnectionString"].ConnectionString;
        
//创建命令字符串
        string comm_string = "select * from clerk";
        
//创建连接对象
        SqlConnection conn = new SqlConnection(conn_string);
        
//创建命令对象
        SqlCommand cmd = new SqlCommand(comm_string);
        
//打开连接
        try {
            
//打开连接
            conn.Open();
            
//为命令对象附加连接
            cmd.Connection = conn;
            
//创建DataReader
            SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);

            GridView1.DataSource 
= dr;
            GridView1.DataBind();

        }

        
finally {
            conn.Close();
        }

两个代码执行的结果相同,都在ClerkList.aspx页面显示了员工列表。
ClerkID RealName JobNum DeptID
1 陈公客 1001 1
2 王公客 1002 1
3 张大客 3001 3
4 李大客 3002 3

如果不用ADO.NET,而使用SQLDataSource来完成这个功能,手工键入代码如下:


using System.Web.Configuration;

    protected void Page_Load(object sender, EventArgs e)
    {
        //取得数据库连接设置
        ConnectionStringSettings conn_string = WebConfigurationManager.ConnectionStrings["CAROAConnectionString"];
        //建立sql命令
        string sql_string = "select * from clerk";
        //建立SqlDataSource
        SqlDataSource sqldsClerkList = new SqlDataSource(conn_string.ConnectionString, sql_string);
        //通过SqlDataSource进行查询
        DataView dv = (DataView)sqldsClerkList.Select(DataSourceSelectArguments.Empty);
        //
        GridView1.DataSource = dv;
        GridView1.DataBind();
    }

根据圣殿祭司的话,以上代码是正宗ASP.NET2.0百分百之纯正语法,虽然我现在还不太明白dataview,dataset,datareader的区别以及适合在何时使用。

如果使用编写效率更高,手工代码更少的可视化方式编写,步骤如下(在实际编程中,我更多的采用这种方法,但是如果需要更灵活的数据操纵,也可以编写CodeBehind):
在ClerkList.aspx中拖入一个SqlDataSource控件,打开智能标签选择配置数据源,在对话框选择已有的连接CAROAConnectionString,接着设置查询语句或者直接从表中选择所需的字段。按下确定,即创建了数据源SqlDataSource1.
自动生成的代码如下:
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:CAROAConnectionString %>"
            SelectCommand
="SELECT * FROM [Clerk]"></asp:SqlDataSource>

再拖入一个GridView控件,设置数据源为SqlDataSource1,一旦设置了数据源,控件则会利用数据源返回的字段刷新自身的列。
自动生成的代码如下:
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ClerkID"
            DataSourceID
="SqlDataSource1">
            
<Columns>
                
<asp:BoundField DataField="Clerk_ID" HeaderText="ClerkID" InsertVisible="False"
                    ReadOnly
="True" SortExpression="ClerkID" />
                
<asp:BoundField DataField="RealName" HeaderText="RealName" SortExpression="RealName" />
                
<asp:BoundField DataField="JobNum" HeaderText="JobNum" SortExpression="JobNum" />
                
<asp:BoundField DataField="DeptID" HeaderText="DeptID" SortExpression="DeptID" />
            
</Columns>
        
</asp:GridView>
如果数据库返回的列不需要做任何格式化,那么就不需要为每个列创建一个BoundField,代码可以进一步简化如下:
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ClerkID"
            DataSourceID
="SqlDataSource1" AutoGenerateColumns="true"/>

以上两个代码实现的效果完全一样。但是后者无法单独设置各个列标题,也无法选择所需的列。

实际上,在本项目中,访问数据库操作采用了分层的概念。app_code中DAL.cs负责底层的数据库操作,各个对象对应的类,比如Clerk.cs则提供了表示层所需的各种业务逻辑。最简单的情况是这样:
Clerk.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

public class Clerk
    
{
        
//该方法返回所有职员列表的Dataset
        public DataSet GetAllClerkList()
        
{
            
return DAL.ExecuteDataset(DAL.CONN_STRING, CommandType.Text,
                
"select * from clerk"null);
        }

    }


前台表示层ClerkList.aspx中拖入一个ObjectDataControl控件,数据源设为业务对象Clerk,数据方法select选择GetAllClerkList(),确定后,再拖一个GridView进来并将之数据源指定为ObjecyDataSource1即可。

采用上面这种方法虽然程序结构上分层了,但是GridView本身内置的Edit,Update方法都无法使用,必须写代码。

下面,我们对返回的员工列表结果做进一步扩展。
原文地址:https://www.cnblogs.com/hulu/p/800575.html