不想當將軍的學生,不是好程序員——數據訪問層DAL——程序結構的思考


源代碼:13033480群共享

郭德綱說的原話是:“不想當裁縫的廚子不是好司機”。

 

他說的是這個意思嗎?

 

又能天天在家做可口的飯菜(你把廚子理解成給別人做飯,那,我就沒辦法了);

又買得起得體漂亮的好衣服(你把裁縫理解成給別人量體裁衣,那,我就沒辦法了);

又開得起寶馬奔馳兜風的人(你把司機理解成給別人賣苦力開破車的人,那,我就沒辦法了);

才能討得美女的歡心。

 

呵呵,仁者見仁,我,也就這智商了…

 

我說的這句“不想當將軍的學生,不是好程序員”,可沒那么繞人:

 

將軍嘛:要有系統的觀點,要指揮別人做事,不需要事事躬親,這是一種思想;

學生嘛:學生的最高境界是什么?是“學士”啦…

“學士”和“戰士”沒什么大的區別啦,一個打仗的專業人士,一個學習的專業人士而已…

程序員嘛:計算機專業的學生,一個有系統觀點的學士,難道不是一個好的程序員嗎??

 

前面,我們已經當好了一個裁縫,量體裁衣,精心打造了一個數據集Model;我們又把ADO.NET的核心類封裝到了SQLHelper中,構建了一個函數集DBUtilty。

那,現在,是時候,我們組建一個職能部門,把那些基礎的臟活、累活都交給他們去做了吧?

 

對了,這個職能部門,就叫做數據訪問層DAL…

 

【操作步驟】

一、添加類庫DAL,在DAL中添加類Category.cs,並在類庫中添加函數GetCategories(),代碼如下:

using System;
using System.Data;
using System.Collections.Generic;
using System.Text;

using System.Data.SqlClient;
using WestGarden.Model;
using WestGarden.DBUtility;

namespace WestGarden.DAL
{
    public class Category
    {
        private const string SQL_SELECT_CATEGORIES = "SELECT CategoryId, Name, Descn FROM Category";
        public IList<CategoryInfo> GetCategories()
        {
            IList<CategoryInfo> categories = new List<CategoryInfo>();

            using (SqlDataReader rdr = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringLocalTransaction, CommandType.Text, SQL_SELECT_CATEGORIES, null))
            {
                while (rdr.Read())
                {
                    CategoryInfo cat = new CategoryInfo(rdr.GetString(0), rdr.GetString(1), rdr.GetString(2));
                    categories.Add(cat);
                }
            }
            return categories;
        }
    }
}

 函數GetCategories()要在SQLHelper中讀取連接字符串,因此,需要在SQLHelper.cs中添加代碼:

public static readonly string ConnectionStringLocalTransaction = ConfigurationManager.ConnectionStrings["NetShopConnString"].ConnectionString;

 

注意添加引用System.Configuration。

二、使用用戶控件

在Web中新建文件夾Controls並在其中添加用戶控件NavigationControl.ascx,窗體頁和代碼頁代碼分別如下:

1、NavigationControl.ascx

 

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="NavigationControl.ascx.cs" Inherits="WestGarden.Web.NavigationControl" %>
<%@ OutputCache Duration="100000" VaryByParam="*" %>

<asp:Repeater ID="repCategories" runat="server">
<HeaderTemplate>
<table cellspacing="0" border="0" style="border-collapse: collapse;">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td class="<%= ControlStyle %>"><asp:HyperLink runat="server" ID="lnkCategory"  NavigateUrl='<%# string.Format("~/Items.aspx?page=0&categoryId={0}", Eval("CategoryId")) %>' Text='<%# Eval("Name") %>' /><asp:HiddenField runat="server" ID="hidCategoryId" Value='<%# Eval("CategoryId") %>' /></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>

 

2、NavigationControl.ascx.cs

using System;
using System.Web.UI.WebControls;
using WestGarden.DAL;

namespace WestGarden.Web {
    public partial class NavigationControl : System.Web.UI.UserControl {
               
        private string controlStyle;

        protected string ControlStyle {
            get { return controlStyle; }
        }
	
        protected void GetControlStyle() {
            if (Request.ServerVariables["SCRIPT_NAME"].ToLower().IndexOf("default.aspx") > 0)
                controlStyle = "navigationLinks";
            else
                controlStyle = "mainNavigation";
        }

        protected void Page_Load(object sender, EventArgs e) {
            GetControlStyle();
            BindCategories();

            string categoryId = Request.QueryString["categoryId"];
            if (!string.IsNullOrEmpty(categoryId))
                SelectCategory(categoryId);
        }

        private void SelectCategory(string categoryId) {
            foreach (RepeaterItem item in repCategories.Items) {
                HiddenField hidCategoryId = (HiddenField)item.FindControl("hidCategoryId");
                if(hidCategoryId.Value.ToLower() == categoryId.ToLower()) {
                    HyperLink lnkCategory = (HyperLink)item.FindControl("lnkCategory");
                    lnkCategory.ForeColor = System.Drawing.Color.FromArgb(199, 116, 3);
                    break;
                }
            }
        }

        private void BindCategories() {
            Category category = new Category();
            repCategories.DataSource = category.GetCategories();
            repCategories.DataBind();            
        }
    }
}

 

三、為Default.aspx添加主題WestGarden並添加樣式表StyleSheet.css,在Default.aspx中應用主題,刪除Default.aspx.cs代碼頁中的代碼及Default.aspx中Reapeter控件,直接把用戶控件拖入到頁面中。

 

【幾點說明】

1、  用戶控件NavigationControl,由於要應用在首頁和母版頁兩個地方,在這兩個地方的樣式是不一樣的,為此,有了函數GetControlStyle(),通過判斷地址中有沒有default.aspx來確定采用什么樣式。

2、  母版頁中的導般欄,選擇點擊分類項后,相應分類項的顏色會改變。為此,有了函數SelectCategory(string categoryId),通過地址欄中獲取的CategoryId,查詢預先放置在HiddenField中的CategoryId,獲取相應的Repeater控件的分類項,並設置相應HyperLink的顏色。

3、  我們把ADO.NET的核心類封裝在SQLHelper.cs中,只要告訴它針對哪個連接,命令類型是什么、命令內容是什么,命令參數是什么,就可以使用其中的通用數據庫訪問函數,完成基本的查詢、更新、插入、刪除操作。

4、  我們把基本的查詢、更新、插入、刪除操作的函數,封裝在數據訪問層DAL中,也就是把訪問數據庫的基本參數:針對哪個連接、命令類型、命令內容、命令參數,都存放在數據訪問層的相應函數中,這樣,上一層,在我們現在這個兩層的結構中的應用層,就不再做那些具體的連接、執行命令操作;不再做那些具體的配置連接字符串、命令內容的操作,只需要簡單發布一個指令,調用一個GetCategories()函數,就一切都OK了,我們,是不是已經由奴隸到將軍了呢????

另:前面,我們十八相送,把ADO.NET核心類送到了類庫DBUtility中的SQLHelp.cs類中,這次,就一次性把查詢商品分類表Name字段的功能段代碼,直接形成GetCategories(),直接放在了數據訪問層,沒有再次來個十八相送,實在只是為了不讓程序員中的有情人,再次傷心過度之原因,特此說明...

版權所有©2012,WestGarden.歡迎轉載,轉載請注明出處.更多文章請參閱博客http://www.cnblogs.com/WestGarden/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM