兩天完成一個小型工程報價系統(三層架構)


花了兩天,整理了一下三層架構,順便練了一個小型三層架構——工程報價系統。

功能很簡單,完成基本的增刪改查

  • 搭建項目三層結構

  • 界面的設計以及美化

  • 分層代碼的設計與實現

  1. 模型層:由於表設計時存在主外鍵關系,故把表映射成對象時添加一個外鍵對象來保存外鍵那張表的相關數據。

 

            // 外鍵實體
            private Product _product;
            private Project _project;

            public Project _Project
            {
                get { return _project; }
                set { _project = value; }
            }

            public Product _Product
            {
                get { return _product; }
                set { _product = value; }
            }

 

  2.數據訪問層:把數據封裝成Model對象的各層之間傳遞

  我個人不喜歡三層之間傳遞DataSet數據集,我的理解是盡量不在BLL層出現DataSet,所以我在DAL層把所有獲取的數據封裝成IEnumerable集合,然后返回。

         protected IEnumerable<ProjectItem> ToModelsByFK(SqlDataReader reader)
         {
             var list = new List<ProjectItem>();
             while (reader.Read())
             {
                 list.Add(ToModelByFK(reader));
             }
             return list;
         }  

      
    public ProjectItem ToModelByFK(SqlDataReader reader)
         {
             ProjectItem projectItem = new ProjectItem();
             projectItem._Product = new Product();
             projectItem._Project = new Project();
             projectItem.ID = (int)ToModelValue(reader, "ID");
             projectItem._Product.ID = (int)ToModelValue(reader, "ProductID");
             projectItem._Project.ID = (int)ToModelValue(reader,"projectID");
             projectItem._Product.Manufacturer = ToModelValue(reader, "Manufacturer").ToString();
             projectItem._Product.Parameters = ToModelValue(reader, "Parameters").ToString();
             projectItem._Product.Price = decimal.Parse( ToModelValue(reader, "Price").ToString());
             projectItem._Product.ProductName = ToModelValue(reader, "ProductName").ToString();
             projectItem._Product.Specification = ToModelValue(reader, "Specification").ToString();
             projectItem._Product.Unit = ToModelValue(reader, "Unit").ToString();
             projectItem.Count = (int)ToModelValue(reader, "Count");
             projectItem.TotalMoney = (decimal)ToModelValue(reader, "TotalMoney");
             projectItem.UnitPrice = (decimal)ToModelValue(reader, "UnitPrice"); 
             return projectItem;
         }
protected object ToModelValue(SqlDataReader reader,string columnName)
        {
            if(reader.IsDBNull(reader.GetOrdinal(columnName)))
            {
                return null;
            }
            else
            {
                return reader[columnName];
            }
        }

使用GetProjectByCondition方法返回一個封裝成對象的 IEnumerable集合

      public IEnumerable<Model.Project> GetProjectByCondition(string projectName, string customerName, string contract, string tel)
        {
            StringBuilder sqlWhere = new StringBuilder("select * from Project where 1=1");
            List<SqlParameter> listParameters = new List<SqlParameter>();
            if (!string.IsNullOrWhiteSpace(projectName))
            {
                sqlWhere.AppendLine(" and projectName like @projectName");
                listParameters.Add(new SqlParameter("projectName", "%" + projectName + "%"));
            }
            if (!string.IsNullOrWhiteSpace(contract))
            {
                sqlWhere.AppendLine(" and Contact like @Contact");
                listParameters.Add(new SqlParameter("Contact", "%" + contract + "%"));
            }
            if (!string.IsNullOrWhiteSpace(customerName))
            {
                sqlWhere.AppendLine(" and customer like @customer");
                listParameters.Add(new SqlParameter("customer", "%" + customerName + "%"));
            }
            if (!string.IsNullOrWhiteSpace(tel))
            {
                sqlWhere.AppendLine(" and tel like @tel");
                listParameters.Add(new SqlParameter("tel", "%" + tel + "%"));
            }
            using (SqlDataReader reader = SqlHelper.ExecuteDataReader(sqlWhere.ToString(), listParameters.ToArray()))
            {
                return ToModels(reader);
            }

        }

UpdatePassChecked方法接受一個對象,通過對象的屬性來獲取數據

  public int UpdatePassChecked(ProjectItem projectItem)
         {
             string sql =
                 "UPDATE Project " +
                 "SET " +
             " ProjectName = @ProjectName"
                 + ", Customer = @Customer"
                 + ", Contact = @Contact"
                 + ", Tel = @Tel"
                 + ", DeliveryPlace = @DeliveryPlace"
                 + ", DeliveryTime = @DeliveryTime"
                 + ", TransportCosts = @TransportCosts"
                 + ", PaymentTerm = @PaymentTerm"
                 + ", Bak = @Bak"

             + " WHERE ID = @ID";


             SqlParameter[] para = new SqlParameter[]
            {
                new SqlParameter("@ID", projectItem._Project.ID)
                    ,new SqlParameter("@ProjectName", ToDBValue(projectItem._Project.ProjectName))
                    ,new SqlParameter("@Customer", ToDBValue(projectItem._Project.Customer))
                    ,new SqlParameter("@Contact", ToDBValue(projectItem._Project.Contact))
                    ,new SqlParameter("@Tel", ToDBValue(projectItem._Project.Tel))
                    ,new SqlParameter("@DeliveryPlace", ToDBValue(projectItem._Project.DeliveryPlace))
                    ,new SqlParameter("@DeliveryTime", ToDBValue(projectItem._Project.DeliveryTime))
                    ,new SqlParameter("@TransportCosts", ToDBValue(projectItem._Project.TransportCosts))
                    ,new SqlParameter("@PaymentTerm", ToDBValue(projectItem._Project.PaymentTerm))
                    ,new SqlParameter("@Bak", ToDBValue(projectItem._Project.Bak))
            };

             return SqlHelper.ExecuteNonQuery(sql, para);

         }

Add方法傳入一個已經把數據封裝好的對象,然后返回一個新的對象(包含新創建生成的ID)

    public Product Add(Product product)
        {
                string sql ="INSERT INTO Product (ProductName, Specification, Manufacturer, Parameters, Price, Unit)  output inserted.ID VALUES (@ProductName, @Specification, @Manufacturer, @Parameters, @Price, @Unit)";
                SqlParameter[] para = new SqlParameter[]
                    {
                        new SqlParameter("@ProductName", ToDBValue(product.ProductName)),
                        new SqlParameter("@Specification", ToDBValue(product.Specification)),
                        new SqlParameter("@Manufacturer", ToDBValue(product.Manufacturer)),
                        new SqlParameter("@Parameters", ToDBValue(product.Parameters)),
                        new SqlParameter("@Price", ToDBValue(product.Price)),
                        new SqlParameter("@Unit", ToDBValue(product.Unit)),
                    };
                    
                int newId = (int)SqlHelper.ExecuteScalar(sql, para);
                return GetByID(newId);
        }

 

  3.業務邏輯層:業務邏輯層是項目的核心,業務邏輯上的代碼通常在這兒實現(一言難盡)。

簡單數據驗證:

        public bool UpdateThroughChecked(ProjectItem projectItem)
        {
            if (string.IsNullOrEmpty(projectItem._Project.ProjectName))
            {
                throw new Exception("項目名稱不能為空");
            }
            //顧客姓名可以為空,但聯系人不能為空,所以數據庫里就應該設計好
            if (string.IsNullOrEmpty(projectItem._Project.Contact))
            {
                throw new Exception("聯系人姓名不能為空");
            }
            if (string.IsNullOrEmpty(projectItem._Project.Tel))
            {
                throw new Exception("聯系電話不能為空");
            }
            if (string.IsNullOrEmpty(projectItem._Project.DeliveryPlace))
            {
                throw new Exception("交貨地點不能為空");
            }
            if (string.IsNullOrEmpty(projectItem._Project.DeliveryTime))
            {
                throw new Exception("交貨時間不能為空");
            }
            if (projectItem._Project.TransportCosts<00)
            {
                throw new Exception("運輸費用不能為負數");
            }
            return new DAL.ProjectItemService().UpdatePassChecked(projectItem) > 0;

        }

計算總金額:

     public decimal GetProductTotalMoney(int projectID)
        {
            var list = new DAL.ProjectItemService().GetProductTotalMoney(projectID);
            decimal  totalMoney = 0.00M;
            foreach (var model in list)
            {
                totalMoney+=model.TotalMoney.Value;
            }
            return totalMoney;
        }

根據查詢條件獲取數據集合:

 /// <summary>
        /// 根據查詢條件獲取數據集合
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public IEnumerable<Model.Product> GetProductsByCondition(string condition)
        {
           return new DAL.ProductService().GetProductsByCondition(condition);
       
        }

根據ProjectItemID獲取一條記錄(封裝成對象)

        public Model.ProjectItem GetOneProjectItemByID(int ProjectItemID)
        {
            return new DAL.ProjectItemService().GetOneProjectItemByID(ProjectItemID);
        }

增加一條記錄:

        /// <summary>
        /// 新增一條記錄 根據條件
        /// </summary>
        /// <param name="modelProject"></param>
        /// <returns></returns>
        public Model.Project AddPassCheckd(Model.Project modelProject)
        {

            if (string.IsNullOrEmpty(modelProject.ProjectName))
            {
                throw new Exception("項目名稱不能為空");
            }
            if (string.IsNullOrEmpty(modelProject.Customer))
            {
                throw new Exception("顧客名稱不能為空");
            }
            if (string.IsNullOrEmpty(modelProject.Tel))
            {
                throw new Exception("聯系電話不能為空");
            }
            if (modelProject.TransportCosts <= 0)
            {
                throw new Exception("運輸費用不能為負數:(");
            }
            return new DAL.ProjectService().Add(modelProject);
           
        }

刪除一個項目:

   /// <summary>
        /// 刪除一個項目
        /// </summary>
        /// <param name="projectID"></param>
        /// <returns></returns>
        public bool DeleteProject(int projectID)
        {
             bool isSucceed=  new BLL.ProjectItemManager().DeleteProjectItemsByProjectID(projectID);
             isSucceed = new DAL.ProjectService().DeleteByID(projectID) > 0 && isSucceed;
             return isSucceed;
        }

4.表現層(UI)

簡單的窗體里嵌套窗體:

        public void LoadProjectListForm()
        {
            projectListForm = null;
            if (projectListForm==null)
            {
                projectListForm = new ProjectListForm();
            }
            //去掉邊框
            projectListForm.FormBorderStyle = FormBorderStyle.None;
            projectListForm.TopLevel = false;//窗體是否是頂級窗體
            projectListForm.Dock = DockStyle.Fill;//填充
            projectListForm.Show();//不寫看不到
            panelContainer.Controls.Clear();//清空
            panelContainer.Controls.Add(projectListForm);
        }

綁定數據:

我原先思路是直接在DataGridView里綁定對象的屬性,和GridView一樣使用,但一直無法綁上去,哪兒錯了?

所以只能曲線救國了:

 void LoadData()
        {
            var list = new BLL.ProjectItemManager().GetAllProducts(projectID);
            //dataGridViewProjectItems.DataSource = list;//當控件被綁定時無法向其添加Row
            dataGridViewProjectItems.Rows.Clear();
            foreach (var model in list)
            {
                int i = dataGridViewProjectItems.Rows.Add();
                dataGridViewProjectItems.Rows[i].Cells["idColumn"].Value = model.ID;
                dataGridViewProjectItems.Rows[i].Cells["specificationColumn"].Value = model._Product.Specification;
                dataGridViewProjectItems.Rows[i].Cells["productNameColumn"].Value = model._Product.ProductName;
                dataGridViewProjectItems.Rows[i].Cells["manufacturerColumn"].Value = model._Product.Manufacturer;
                dataGridViewProjectItems.Rows[i].Cells["parametersColumn"].Value = model._Product.Parameters;
                dataGridViewProjectItems.Rows[i].Cells["productIDColumn"].Value = model._Product.ID;
                dataGridViewProjectItems.Rows[i].Cells["totalMoneyColumn"].Value = model.TotalMoney;
                dataGridViewProjectItems.Rows[i].Cells["countColumn"].Value = model.Count;
                dataGridViewProjectItems.Rows[i].Cells["unitPriceColumn"].Value = model.UnitPrice;
                dataGridViewProjectItems.Rows[i].Cells["projectIDColumn"].Value = model._Project.ID;
            }

5.項目總結

花了一個周末修修補補完成了這個工程報價系統,算是復習了一把三層架構。

如果有需要這個項目的朋友可以留下郵箱,我發給你,不算很專業,湊合着參考下~~

沒想到這么多朋友要我的源碼,我很感動。附件我就不傳了,我也怕誤導新人。有需要的朋友可以留下郵箱,大家一起探討,我的代碼純當入門階段,是我個人對三層架構的理解,不足之處,也請多多包涵,提個意見,希望與君互勉。想要更深刻探索我推介《ASP.NET 設計模式》


 源代碼下載:


免責聲明!

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



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