零基礎學C#3.0 -- .net的三層架構

新手學C# ——.net的三層架構之最簡單實例:登陸界面sql

 

三層架構包括:數據庫

1. 數據訪問層(Data Access Layer, DAL):負責將底層數據傳送到業務邏輯層架構

2. 業務邏輯層(Business Logic Layer, BLL):處理數據訪問層傳送的數據,並實現業務邏輯函數

3. 表示層(User Interface, UI):不處理任何業務,負責顯示與實時更新學習

其中1--2--3層次依次上升。this

爲了使信息可以順利由底層傳送,能夠採用實體類的方法,添加實體層。實體類一般與數據庫中字段相互對應,擁有get和set屬性。實體類的目的是用於替代DataSet,經過類的方式傳遞數據,並使邏輯更加清晰。spa

三層架構來源於MVC,其核心思想是保持三層之間的相互獨立,在對其餘功能進行局部修改時,可使三層結構保持大致不變,以避免進行全局的修改。換句話說,在修改某局部代碼後,你天然而然的知道何處的代碼應該進行修改何處的代碼能夠不進行修改如何規範修改的局部代碼對上層的接口以達到減小修改量的目的.net

這裏不得不說的是,在三層架構中,修改局部代碼對總體的變更仍是很大的,層次數越多,須要修改的部分越少。固然,層次數的增長伴隨着邏輯的複雜性增長和接口的複雜性增長。越是小型的項目,須要的層次數越少。code

下面舉一個最簡單的例子:用戶登陸。orm

 

數據庫中表Login的結構:

LoginID : 用戶名

LoginPwd : 用戶密碼

 

(1)新建一個WinForm項目SchoolManager,在項目解決方案中點擊右鍵新建三個類庫(SchoolManager.DAL, SchoolManager.BLL, SchoolManager.Model),分別表示數據訪問層、業務邏輯層和實體層。

(2)右鍵單擊類庫,添加引用(BLL引用DAL,UI引用BLL,三者都引用Model),表達四者之間的邏輯依賴關係。這裏強調的是,UI不引用DAL。

(3)編寫實體類Login.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SchoolManager.Model
{
    public class Login
    {
        private int stuID;  //學號
        public int StuID
        {
            get { return stuID; }
            set { stuID = value; }
        }

        private string studentName;  //姓名
        public string StudentName
        {
            get { return studentName; }
            set { studentName = value; }
        }

        private string loginID;  //登陸名
        public string LoginID
        {
            get { return loginID; }
            set { loginID = value; }
        }

        private string loginPwd;  //登陸密碼
        public string LoginPwd 
        {
            get { return loginPwd; }
            set { loginPwd = value; }
        }

        private int state;
        public int State 
        {
            get { return state; }
            set { state = value; }
        }

    }
}

這個實體類與數據庫中的表一一對應(這裏沒有對應的緣由是實際程序中只用到了兩個字段,實際數據庫中的表以此類中的字段爲準),也就是說,數據庫中表的每一行均可以轉化爲這個類中的一個實例,從而在各個層中傳遞數據。

(4)編寫DAL類LoginService.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SchoolManager.Model;
using System.Data.SqlClient;

namespace SchoolManager.DAL
{
    public static class LoginService
    {
        static string connStr = @"Data Source=(local)\SQLEXPRESS;Initial Catalog=StudentInfo;Integrated Security=True;Pooling=False";
        private static SqlConnection sqlConn = new SqlConnection(connStr);

        /// <summary>
        /// 根據登陸名返回用戶類
        /// </summary>
        /// <param name="loginID">登陸名</param>
        /// <returns>用戶類</returns>
        public static Login GetLoginByLoginID(string loginID)
        {
            string sql = "select * from Login where LoginID='" + loginID + "'";
            try
            {
                SqlCommand sqlCmd = new SqlCommand(sql, sqlConn);
                sqlConn.Open();
                SqlDataReader sqlReader = sqlCmd.ExecuteReader();
                if (sqlReader.Read())
                {
                    Login user = new Login();
                    user.LoginID = Convert.ToString(sqlReader["LoginID"]);
                    user.LoginPwd = Convert.ToString(sqlReader["LoginPwd"]);
                    user.State = Convert.ToInt32(sqlReader["State"]);
                    user.StudentName = Convert.ToString(sqlReader["StudentName"]);
                    user.StuID = Convert.ToInt32(sqlReader["StuID"]);
                    sqlReader.Close();
                    sqlConn.Close();
                    return user;
                }
                else
                {
                    sqlConn.Close();
                    sqlReader.Close();
                    return null;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw ex;
            }
        }
    }
}

這裏注意幾點:

a)此類(以及以後的BLL,UI)引入了Model的命名空間,從而能夠調用Model中的Login類並生成實例,這正是添加引用的緣由所在。

b)此類引入了System.Data.SqlClient,也是這三層中惟一引用這個命名空間的層,即全部對數據庫的操做都要在這一層的不一樣類中完成。

c)GetLoginByLoginIn()方法的返回值是Login類的一個實例,實質上是返回查詢後的指定行數據。

(5)編寫BLL類LoginManager.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SchoolManager.Model;
using SchoolManager.DAL;

namespace SchoolManager.BLL
{
    public class LoginManager
    {
        /// <summary>
        /// 從數據訪問層調用數據的方法
        /// </summary>
        /// <param name="loginID">登陸名</param>
        /// <returns>密碼是否匹配</returns>
        public static bool GetLogin(string loginID, string loginPwd)
        {
            Login user = LoginService.GetLoginByLoginID(loginID);
            if (user.LoginPwd == loginPwd)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

    }
}

注意如下幾點:

a)引用了DAL的命名空間,由於要調用DAL中的GetLoginByLoginIn()方法。

b)GetLogin()實際上已經完成了用戶登陸的邏輯功能,不能將判斷式寫入UI層中。

(6)編寫UI層LoginForm.cs:(界面很簡潔,用戶名、密碼輸入框,肯定、取消按鈕)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SchoolManager.Model;
using SchoolManager.BLL;

namespace SchoolManager
{
    public partial class LoginForm : Form
    {
        public LoginForm()
        {
            InitializeComponent();
        }

        private void buttonLogin_Click(object sender, EventArgs e)
        {
            //檢測用戶名是否爲空
            if(string.IsNullOrEmpty(textBoxName.Text))
            {
                MessageBox.Show("請輸入用戶名");
                return;
            }

            //檢測密碼是否爲空
            if (string.IsNullOrEmpty(textBoxPwd.Text))
            {
                MessageBox.Show("請輸入密碼");
                return;
            }

            //調用業務邏輯層方法登陸
            if(LoginManager.GetLogin(textBoxName.Text, textBoxPwd.Text))
            {
                MessageBox.Show("登錄成功");
            }
            else
            {
                MessageBox.Show("用戶名或密碼錯誤");
            }
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

    }
}

這裏有幾點須要注意:

a)引用命名空間(詳見上文)

b)對TextBox中是否爲空的判斷能夠由UI層完成,也能夠在BLL層中編寫Validate()函數並在UI層中調用,不過仍是建議在UI層中完成,畢竟界面的修改必然伴隨着Validate()方法的修改

c)UI層調用GetLogin()方法以後,只是將返回的布爾值解釋爲登陸成功/失敗,沒有進行邏輯上的判斷。

 

但願本文能對.net學習的菜鳥級新手有所幫助!(本人也處於這一行列)

相關文章
相關標籤/搜索