循序漸進開發WinForm項目(1) --數據庫設計和項目框架的生成


隨筆背景:在很多時候,很多入門不久的朋友都會問我:我是從其他語言轉到C#開發的,有沒有一些基礎性的資料給我們學習學習呢,你的框架感覺一下太大了,希望有個循序漸進的教程或者視頻來學習就好了。

其實也許我們每天面對的太多東西了,覺得很多都稀松平常了,即使很細微的地方,可能我們都已經形成習慣了。反過來,如果我們切換到其他領域,如IOS、android,那么開始我們可能對里面很多設計的規則不甚了解,開始可能也是一頭霧水。

本篇想作為我的《循序漸進開發WinForm項目》系列的開篇,主要介紹數據庫設計方面注意的一些事項,從而方便項目框架的搭建和開發過程。

1、數據庫表設計

俗話說萬層高樓從底起,開發應用項目,數據庫的設計很重要,它可能是業務對象,業務流程的綜合設計,好的數據庫設計可以減少后期的重復返工,提高開發效率。

我們以一個簡單的數據庫表進行設計討論,一步步分析其中的關系。

1)表和字段名稱

一般表名稱,根據不同的業務關系,我們可以使用不同的前綴進行區分,使用前綴,可以非常方便區分不同的業務表,如我自己一般基礎表使用 “TB_” 定義前綴,權限系統表使用"T_ACL_"定義前綴,工作流表使用“TBAPP_”,業務表使用"T_"等,這樣對於區分不同的業務,方便管理很有好處。

字段名稱方面,我們可以約定一些規則,如約定主鍵使用ID;一般來說,ID作為主鍵,可以使用自增長的整形字段,也可以使用GUID的字符型字段,如果為了方便兼容不同的數據庫且方便遷移或者開發基於網絡方面的應用,我建議還是使用GUID的字符型字段,使用這種類型的字段,我們從創建數據的時候,就可以知道這個記錄的主鍵,對於我們維護父子表等關系非常有利。

字段的命名,建議一簡單為主,如客戶名稱,直接使用Name來命名即可,不需要使用CustomerName這樣啰嗦的名稱。

由於如果采用字符型的ID主鍵,那么我們如果需要正確排序的時候,可能需要增加一個CreateTime的日期類型,方便我們根據日期進行排序。

如果這個表還有一個外鍵的引用,建議統一命名標准,我一般使用“表名稱_ID這樣的名稱,如User_ID、Contact_ID等相似的名稱作為外鍵,不需要表的前綴。

2)數據庫的模型設計

數據庫的模型設計,我們建議在第三方的數據庫設計工具上進行設計,如PowerDesigner這樣的設計工具,使用工具設計數據庫有很多好處,一個是可以高效率進行調整,二是根據需要生成不同的數據庫類型Sql語句,三是可以全局了解各個表之間的關系等等。

使用PowerDesigner這樣的數據庫設計工具,能夠在很大程度上提高我們數據庫的設計效率。

 

2、項目框架的生成

設計好數據庫后,我們通過代碼生成工具進行整個項目框架的生成,這樣對於我們在開發新項目上有很好的好處,里面的項目層級、DLL的 引用關系,已經處理好了,這樣對我們非常方便。不過大多數情況下,我們都是增量開發較多,也就是我們可能前面已經完成了一些其他業務的開發,可能新增一個兩個表,或者一批業務表的處理,這樣也沒關系,我們把新生成的代碼復制到項目即可,由於項目生成的時候,指定了主命名空間和相關的表前綴,這樣我們生成后的代碼就方便閱讀很多,減少累贅和出錯的機會。

WInform開發框架,常見的分層模式,可以分為UI層、BLL層、DAL層、IDAL層、Entity層、公用類庫層等等

這個分層,在Web項目或者WInform項目(包括WPF項目)這些分層都是可以重用的,這樣我們就不用重復處理界面一下的邏輯,針對性的開發我們需要的界面層即可。

DAL層根據不同的需要,擴展支持不同的數據庫類型,每個數據庫類型,對應一個數據庫訪問實現層即可,它們實現IDAL層的接口,稱之為數據庫訪問接口實現層。

如果我們選擇開發混合型開發應用,我們可能還會有一些WCF的服務邏輯層、WCF服務層、客戶端調用層、界面層(后面再介紹)等方面,如下的項目結構所示。

 

3、項目代碼分析

通過代碼工具,我們已經可以完整生成基礎的項目框架了,下面我們來分析下項目的源碼,從而知道整個框架的架構和代碼的層次是如何的。

剛才我們看到,生成的項目里面,已經包含了實體類,我們以開篇介紹的一個表生成的代碼來進行研究分析。

生成的實體類代碼如下所示

    /// <summary>
    /// 客戶信息
    /// </summary>
    [DataContract]
    public class CustomerInfo : BaseEntity
    {    
        #region Field Members

        private string m_ID = System.Guid.NewGuid().ToString(); //編號          
        private string m_Name; //姓名          
        private int m_Age = 0; //年齡          
        private string m_Creator; //創建人          
        private DateTime m_CreateTime; //創建時間          

        #endregion

        #region Property Members
        
        /// <summary>
        /// 編號
        /// </summary>
        [DataMember]
        public virtual string ID
        {
            get
            {
                return this.m_ID;
            }
            set
            {
                this.m_ID = value;
            }
        }

        /// <summary>
        /// 姓名
        /// </summary>
        [DataMember]
        public virtual string Name
        {
            get
            {
                return this.m_Name;
            }
            set
            {
                this.m_Name = value;
            }
        }

        /// <summary>
        /// 年齡
        /// </summary>
        [DataMember]
        public virtual int Age
        {
            get
            {
                return this.m_Age;
            }
            set
            {
                this.m_Age = value;
            }
        }

        /// <summary>
        /// 創建人
        /// </summary>
        [DataMember]
        public virtual string Creator
        {
            get
            {
                return this.m_Creator;
            }
            set
            {
                this.m_Creator = value;
            }
        }

        /// <summary>
        /// 創建時間
        /// </summary>
        [DataMember]
        public virtual DateTime CreateTime
        {
            get
            {
                return this.m_CreateTime;
            }
            set
            {
                this.m_CreateTime = value;
            }
        }


        #endregion

    }
View Code

其中我們看到下面的代碼,里面使用了基類 BaseEntity,這個是所有生成的實體類的基類,基類BaseEntity只是一個實體類的聲明,沒有什么屬性,使用這個實體類基類,只是為了整個框架更好管理和控制。BaseEntity來源於公用類庫,已經封裝在里面了。

    /// <summary>
    /// 客戶信息
    /// </summary>
    [DataContract]
    public class CustomerInfo : BaseEntity
    {    

另外,我們看到,實體類有注釋,這些注釋來自數據庫的備注信息,包括字段的注釋也是來自數據庫的備注說明信息。

還有類的定義里面,還看到了[DataContract] 的標簽,以及類的屬性[DataMember],這個是WCF技術里面傳輸數據的協議聲明,我們目前開發的應用,一般都是基於.NET4.0的了,因此包含這個屬性方便我們在開發網絡版項目的時候用到,一般情況下忽略即可。

我們繼續看看實體類的其他部分代碼:

        #region Field Members

        private string m_ID = System.Guid.NewGuid().ToString(); //編號          
        private string m_Name; //姓名          
        private int m_Age = 0; //年齡          
        private string m_Creator; //創建人          
        private DateTime m_CreateTime; //創建時間          

        #endregion

我們看到,對於字符型的ID主鍵字段,代碼生成的時候,已經自動添加默認屬性值(GUID:System.Guid.NewGuid().ToString() )的了,這樣我們創建實體類的時候,這個ID的值就已經生成了。

好了,基於篇幅的原因,下次繼續介紹項目框架代碼的各部分組成,以及他們之間的關系,注意的實現和內在約定等內容。

 


免責聲明!

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



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