兩天完成一個小型工程報價系統(tǒng)(三層架構)
花了兩天,整理了一下三層架構,順便練了一個小型三層架構——工程報價系統(tǒng)。
功能很簡單,完成基本的增刪改查
- 搭建項目三層結構
- 界面的設計以及美化
#p#
- 分層代碼的設計與實現(xiàn)
1.模型層:由于表設計時存在主外鍵關系,故把表映射成對象時添加一個外鍵對象來保存外鍵那張表的相關數(shù)據(jù)。
- // 外鍵實體
- 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.數(shù)據(jù)訪問層:把數(shù)據(jù)封裝成Model對象的各層之間傳遞。
我個人不喜歡三層之間傳遞DataSet數(shù)據(jù)集,我的理解是盡量不在BLL層出現(xiàn)DataSet,所以我在DAL層把所有獲取的數(shù)據(jù)封裝成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方法接受一個對象,通過對象的屬性來獲取數(shù)據(jù)
- 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方法傳入一個已經(jīng)把數(shù)據(jù)封裝好的對象,然后返回一個新的對象(包含新創(chuàng)建生成的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);
- }
#p#
3.業(yè)務邏輯層:業(yè)務邏輯層是項目的核心,業(yè)務邏輯上的代碼通常在這兒實現(xiàn)(一言難盡)。
簡單數(shù)據(jù)驗證:
- public bool UpdateThroughChecked(ProjectItem projectItem)
- {
- if (string.IsNullOrEmpty(projectItem._Project.ProjectName))
- {
- throw new Exception("項目名稱不能為空");
- }
- //顧客姓名可以為空,但聯(lián)系人不能為空,所以數(shù)據(jù)庫里就應該設計好
- if (string.IsNullOrEmpty(projectItem._Project.Contact))
- {
- throw new Exception("聯(lián)系人姓名不能為空");
- }
- if (string.IsNullOrEmpty(projectItem._Project.Tel))
- {
- throw new Exception("聯(lián)系電話不能為空");
- }
- 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("運輸費用不能為負數(shù)");
- }
- 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;
- }
根據(jù)查詢條件獲取數(shù)據(jù)集合:
- /// <summary>
- /// 根據(jù)查詢條件獲取數(shù)據(jù)集合
- /// </summary>
- /// <param name="condition"></param>
- /// <returns></returns>
- public IEnumerable<Model.Product> GetProductsByCondition(string condition)
- {
- return new DAL.ProductService().GetProductsByCondition(condition);
- }
根據(jù)ProjectItemID獲取一條記錄(封裝成對象)
- public Model.ProjectItem GetOneProjectItemByID(int ProjectItemID)
- {
- return new DAL.ProjectItemService().GetOneProjectItemByID(ProjectItemID);
- }
增加一條記錄:
- /// <summary>
- /// 新增一條記錄 根據(jù)條件
- /// </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("聯(lián)系電話不能為空");
- }
- if (modelProject.TransportCosts <= 0)
- {
- throw new Exception("運輸費用不能為負數(shù):(");
- }
- 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.表現(xiàn)層(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);
- }
綁定數(shù)據(jù):
我原先思路是直接在DataGridView里綁定對象的屬性,和GridView一樣使用,但一直無法綁上去,哪兒錯了? |
所以只能曲線救國了:
|
5.項目總結
花了一個周末修修補補完成了這個工程報價系統(tǒng),算是復習了一把三層架構。
如果有需要這個項目的朋友可以留下郵箱,我發(fā)給你,不算很專業(yè),湊合著參考下~~
沒想到這么多朋友要我的源碼,我很感動。附件我就不傳了,我也怕誤導新人。有需要的朋友可以留下郵箱,大家一起探討,我的代碼純當入門階段,是我個人對三層架構的理解,不足之處,也請多多包涵,提個意見,希望與君互勉。想要更深刻探索我推介《ASP.NET 設計模式》 |
原文鏈接:http://www.cnblogs.com/OceanEyes/archive/2012/06/18/project.html