C#使用三層架構(gòu)開發(fā)Winform的詳細(xì)案例
三層架構(gòu)將整個業(yè)務(wù)應(yīng)用劃分為:
- (1)界面UI層
- (2)業(yè)務(wù)邏輯層
- (3)數(shù)據(jù)訪問層
對于復(fù)雜的系統(tǒng)分層可以讓結(jié)構(gòu)更加清晰,模塊更加獨立,便于維護。
各層的任務(wù):
- (1)數(shù)據(jù)訪問層:負(fù)責(zé)數(shù)據(jù)庫的操作。
- (2)業(yè)務(wù)邏輯層:實現(xiàn)功能模塊的業(yè)務(wù)邏輯。
- (3)界面UI層:繪制界面,以及負(fù)責(zé)界面相關(guān)代碼。
- (4)實體類:將數(shù)據(jù)庫中的表轉(zhuǎn)化為面向?qū)ο笏枷胫械念悺?/li>
一、案例需求
使用三層架構(gòu)實現(xiàn)學(xué)生管理:
(1)專業(yè)下拉框綁定專業(yè)表數(shù)據(jù),網(wǎng)格控件綁定學(xué)生數(shù)據(jù),并且點擊"搜索"按鈕可以多條件組合查詢。
(2)選中某一行,右鍵可以彈出"刪除"菜單,點擊"刪除"菜單可以刪除學(xué)生數(shù)據(jù)。
(3)點擊"新增"按鈕,彈出新增窗體,在此窗體中完成學(xué)生的新增操作。
(4)選中某一行,點擊"編輯"按鈕,彈出編輯窗體,在此窗體中完成數(shù)據(jù)的修改。
備注:其中性別的單選框,以及愛好的多選框分別用兩個Pannel容器包含。
數(shù)據(jù)庫準(zhǔn)備:
--專業(yè) create table ProfessionInfo ( ProfessionID int primary key identity(1,1), --專業(yè)編號 ProfessionName varchar(50) not null unique --專業(yè)名稱 ) --學(xué)生 create table StudentInfo ( StuID varchar(20) primary key, --學(xué)生學(xué)號 StuName varchar(50) not null, --學(xué)生姓名 StuAge int not null check(StuAge > 0 and StuAge < 130), --學(xué)生年齡 StuSex char(2) not null check(StuSex in('男','女')), --學(xué)生性別 StuHobby nvarchar(100), --愛好 ProfessionID int not null references ProfessionInfo(ProfessionID), --所屬專業(yè)編號 ) --添加專業(yè)信息 insert into ProfessionInfo(ProfessionName) values('電子競技') insert into ProfessionInfo(ProfessionName) values('軟件開發(fā)') insert into ProfessionInfo(ProfessionName) values('醫(yī)療護理') --插入學(xué)生信息 insert into StudentInfo(StuID,StuName,StuAge,StuSex,StuHobby,ProfessionID) values('001','劉備',18,'男','',1) insert into StudentInfo(StuID,StuName,StuAge,StuSex,StuHobby,ProfessionID) values('002','關(guān)羽',20,'男','',2) insert into StudentInfo(StuID,StuName,StuAge,StuSex,StuHobby,ProfessionID) values('003','張飛',19,'男','',2) insert into StudentInfo(StuID,StuName,StuAge,StuSex,StuHobby,ProfessionID) values('004','孫尚香',17,'女','',3)
二、項目結(jié)構(gòu)
(1)創(chuàng)建一個空白解決方案。
(2)在解決方案中創(chuàng)建類庫項目MyEntity代表"實體類"。
(3)在解決方案中創(chuàng)建類庫項目MyDAL代表"數(shù)據(jù)訪問層"。
(4)在解決方案中創(chuàng)建類庫項目MyBLL代表"業(yè)務(wù)邏輯層"。
(5)在解決方案中創(chuàng)建Windows窗體應(yīng)用程序MyUI代表"界面UI層"。
三、實體類編寫
在MyEntity項目中添加兩個實體類,實體類代碼如下:
ProfessionInfoEntity:
public class ProfessionInfoEntity { public ProfessionInfoEntity() { this.ProfessionID = 0; this.ProfessionName = ""; } public int ProfessionID { get; set; } //專業(yè)編號 public string ProfessionName { get; set; }//專業(yè)名稱 }
StudentInfoEntiy:
public class StudentInfoEntiy { public StudentInfoEntiy() { this.StuID = ""; this.StuName = ""; this.StuAge = 0; this.StuSex = ""; this.StuHobby = ""; this.ProfessionID = 0; this.ProfessionName = ""; } public string StuID { get; set; } //學(xué)生學(xué)號 public string StuName { get; set; } //學(xué)生姓名 public int StuAge { get; set; } //學(xué)生年齡 public string StuSex { get; set; } //學(xué)生性別 public string StuHobby { get; set; } //學(xué)生愛好 public int ProfessionID { get; set; } //學(xué)生所屬專業(yè)編號 public string ProfessionName { get; set; } //學(xué)生所屬專業(yè)名稱 }
四、數(shù)據(jù)訪問層編寫
(1)由于數(shù)據(jù)訪問層需要使用實體類,所以需要添加實體類的引用。
即在MyDAL項目上右鍵-->添加-->引用-->項目,在項目中勾選MyEntity項目。
(2)將之前封裝好的DBHelper文件復(fù)制到MyDAL項目中,并通過添加現(xiàn)有項,將DBHelper加入項目。
(3)在MyDAL項目中添加兩個類,類代碼如下:
ProfessionInfoDAL:
public class ProfessionInfoDAL { #region 新增 public int Add(ProfessionInfoEntity entity) { string sql = "insert into ProfessionInfo(professionName) values(@professionName)"; DBHelper.PrepareSql(sql); DBHelper.SetParameter("ProfessionName",entity.ProfessionName); return DBHelper.ExecNonQuery(); } #endregion #region 刪除 public int Delete(int id) { string sql = "delete from ProfessionInfo where ProfessionID=@ProfessionID"; DBHelper.PrepareSql(sql); DBHelper.SetParameter("ProfessionID", id); return DBHelper.ExecNonQuery(); } #endregion #region 修改 public int Update(ProfessionInfoEntity entity) { string sql = "update ProfessionInfo set professionName=@professionName where ProfessionID=@ProfessionID"; DBHelper.PrepareSql(sql); DBHelper.SetParameter("professionName", entity.ProfessionName); DBHelper.SetParameter("ProfessionID", entity.ProfessionID); return DBHelper.ExecNonQuery(); } #endregion #region 列表 public List<ProfessionInfoEntity> List() { string sql = "select * from ProfessionInfo"; DataTable dt = new DataTable(); DBHelper.PrepareSql(sql); dt = DBHelper.ExecQuery(); List<ProfessionInfoEntity> list = new List<ProfessionInfoEntity>(); foreach (DataRow item in dt.Rows) { ProfessionInfoEntity entity = new ProfessionInfoEntity(); entity.ProfessionID = int.Parse(item["ProfessionID"].ToString()); entity.ProfessionName = item["ProfessionName"].ToString(); list.Add(entity); } return list; } #endregion #region 詳情 public ProfessionInfoEntity Detail(int id) { string sql = "select * from ProfessionInfo where ProfessionID=@ProfessionID"; DataTable dt = new DataTable(); DBHelper.PrepareSql(sql); DBHelper.SetParameter("ProfessionID", id); dt = DBHelper.ExecQuery(); if (dt.Rows.Count == 0) return null; ProfessionInfoEntity entity = new ProfessionInfoEntity(); entity.ProfessionID = int.Parse(dt.Rows[0]["ProfessionID"].ToString()); entity.ProfessionName = dt.Rows[0]["ProfessionName"].ToString(); return entity; } #endregion }
StudentInfoDAL:
public class StudentInfoDAL { #region 新增 public int Add(StudentInfoEntiy entity) { string sql = "insert into StudentInfo(StuID,StuName,StuAge,StuSex,StuHobby,ProfessionID) values(@StuID,@StuName,@StuAge,@StuSex,@StuHobby,@ProfessionID)"; DBHelper.PrepareSql(sql); DBHelper.SetParameter("StuID", entity.StuID); DBHelper.SetParameter("StuName", entity.StuName); DBHelper.SetParameter("StuAge", entity.StuAge); DBHelper.SetParameter("StuSex", entity.StuSex); DBHelper.SetParameter("StuHobby", entity.StuHobby); DBHelper.SetParameter("ProfessionID", entity.ProfessionID); return DBHelper.ExecNonQuery(); } #endregion #region 刪除 public int Delete(string id) { string sql = "delete from StudentInfo where StuID=@StuID"; DBHelper.PrepareSql(sql); DBHelper.SetParameter("StuID", id); return DBHelper.ExecNonQuery(); } #endregion #region 修改 public int Update(StudentInfoEntiy entity) { string sql = "update StudentInfo set StuName=@StuName,StuAge=@StuAge,StuSex=@StuSex,StuHobby=@StuHobby,ProfessionID=@ProfessionID where StuID=@StuID"; DBHelper.PrepareSql(sql); DBHelper.SetParameter("StuName", entity.StuName); DBHelper.SetParameter("StuAge", entity.StuAge); DBHelper.SetParameter("StuSex", entity.StuSex); DBHelper.SetParameter("StuHobby", entity.StuHobby); DBHelper.SetParameter("ProfessionID", entity.ProfessionID); DBHelper.SetParameter("StuID", entity.StuID); return DBHelper.ExecNonQuery(); } #endregion #region 列表 public List<StudentInfoEntiy> List() { string sql = "select * from StudentInfo"; DataTable dt = new DataTable(); DBHelper.PrepareSql(sql); dt = DBHelper.ExecQuery(); List<StudentInfoEntiy> list = new List<StudentInfoEntiy>(); foreach (DataRow item in dt.Rows) { StudentInfoEntiy entity = new StudentInfoEntiy(); entity.StuID = item["StuID"].ToString(); entity.StuName = item["StuName"].ToString(); entity.StuAge = int.Parse(item["StuAge"].ToString()); entity.StuSex = item["StuSex"].ToString(); entity.StuHobby = item["StuHobby"].ToString(); entity.ProfessionID = int.Parse(item["ProfessionID"].ToString()); list.Add(entity); } return list; } #endregion #region 詳情 public StudentInfoEntiy Detail(string id) { string sql = "select * from StudentInfo where StuID=@StuID"; DataTable dt = new DataTable(); DBHelper.PrepareSql(sql); DBHelper.SetParameter("StuID", id); dt = DBHelper.ExecQuery(); if (dt.Rows.Count == 0) return null; StudentInfoEntiy entity = new StudentInfoEntiy(); entity.StuID = dt.Rows[0]["StuID"].ToString(); entity.StuName = dt.Rows[0]["StuName"].ToString(); entity.StuAge = int.Parse(dt.Rows[0]["StuAge"].ToString()); entity.StuSex = dt.Rows[0]["StuSex"].ToString(); entity.StuHobby = dt.Rows[0]["StuHobby"].ToString(); entity.ProfessionID = int.Parse(dt.Rows[0]["ProfessionID"].ToString()); return entity; } #endregion }
五、業(yè)務(wù)邏輯層編寫
(1)由于業(yè)務(wù)邏輯層需要使用實體類,所以需要添加實體類的引用。
即在MyBLL項目上右鍵-->添加-->引用-->項目,在項目中勾選MyEntity項目。
(2)由于業(yè)務(wù)邏輯層需要調(diào)用數(shù)據(jù)訪問層,所以需要添加數(shù)據(jù)訪問層的引用。
即在MyBLL項目上右鍵-->添加-->引用-->項目,在項目中勾選MyDAL項目。
(3)在MyBLL項目中添加兩個類,類代碼如下:
ProfessionInfoBLL:
public class ProfessionInfoBLL { ProfessionInfoDAL dal = new ProfessionInfoDAL(); #region 新增 public int Add(ProfessionInfoEntity entity) { return dal.Add(entity); } #endregion #region 刪除 public int Delete(int id) { return dal.Delete(id); } #endregion #region 修改 public int Update(ProfessionInfoEntity entity) { return dal.Update(entity); } #endregion #region 列表 public List<ProfessionInfoEntity> List() { return dal.List(); } #endregion #region 詳情 public ProfessionInfoEntity Detail(int id) { return dal.Detail(id); } #endregion }
StudentInfoBLL:
public class StudentInfoBLL { StudentInfoDAL dal = new StudentInfoDAL(); #region 新增 public int Add(StudentInfoEntiy entity) { return dal.Add(entity); } #endregion #region 刪除 public int Delete(string id) { return dal.Delete(id); } #endregion #region 修改 public int Update(StudentInfoEntiy entity) { return dal.Update(entity); } #endregion #region 列表 public List<StudentInfoEntiy> List() { return dal.List(); } #endregion #region 詳情 public StudentInfoEntiy Detail(string id) { return dal.Detail(id); } #endregion }
六、界面UI層代碼編寫
(1)由于界面UI層需要使用實體類,所以需要添加實體類的引用。
即在MyUI項目上右鍵-->添加-->引用-->項目,在項目中勾選MyEntity項目。
(2)由于界面UI層需要調(diào)用業(yè)務(wù)邏輯層,所以需要添加業(yè)務(wù)邏輯層的引用。
即在MyUI項目上右鍵-->添加-->引用-->項目,在項目中勾選MyBLL項目。
查詢窗體界面及代碼:
(1)由于查詢學(xué)生需要多條件組合查詢,所以給數(shù)據(jù)訪問層和業(yè)務(wù)邏輯層添加條件搜索的方法。
給數(shù)據(jù)訪問層MyDAL中StudentInfoDAL類添加方法:
#region 條件查詢 public List<StudentInfoEntiy> Search(StudentInfoEntiy searchObj) { string sql = "select * from StudentInfo inner join ProfessionInfo on StudentInfo.ProfessionID = ProfessionInfo.ProfessionID where 1 = 1"; if (searchObj.ProfessionID != 0) sql += " and StudentInfo.ProfessionID = " + searchObj.ProfessionID; if (!searchObj.StuName.Equals("")) sql += " and StuName like '%" + searchObj.StuName + "%'"; DataTable dt = new DataTable(); DBHelper.PrepareSql(sql); dt = DBHelper.ExecQuery(); List<StudentInfoEntiy> list = new List<StudentInfoEntiy>(); foreach (DataRow item in dt.Rows) { StudentInfoEntiy entity = new StudentInfoEntiy(); entity.StuID = item["StuID"].ToString(); entity.StuName = item["StuName"].ToString(); entity.StuAge = int.Parse(item["StuAge"].ToString()); entity.StuSex = item["StuSex"].ToString(); entity.StuHobby = item["StuHobby"].ToString(); entity.ProfessionID = int.Parse(item["ProfessionID"].ToString()); entity.ProfessionName = item["ProfessionName"].ToString(); list.Add(entity); } return list; } #endregion
給業(yè)務(wù)邏輯層MyBLL中StudentInfoBLL類添加方法:
#region 條件查詢 public List<StudentInfoEntiy> Search(StudentInfoEntiy searchObj) { return dal.Search(searchObj); } #endregion
(2)在此界面中多個功能需要調(diào)用業(yè)務(wù)邏輯層,定義兩個業(yè)務(wù)邏輯層對象:
ProfessionInfoBLL proBll = new ProfessionInfoBLL(); StudentInfoBLL stuBll = new StudentInfoBLL();
(3)查詢窗體綁定專業(yè)信息、綁定學(xué)生信息以及搜索功能代碼:
#region 綁定下拉框 private void BindPro() { List<ProfessionInfoEntity> list = new List<ProfessionInfoEntity>(); list = proBll.List(); list.Insert(0,new ProfessionInfoEntity { ProfessionID=0,ProfessionName="--請選擇--"}); this.cmbPro.DataSource = list; this.cmbPro.DisplayMember = "ProfessionName"; this.cmbPro.ValueMember = "ProfessionID"; } #endregion #region 綁定學(xué)生數(shù)據(jù) private void BindData() { StudentInfoEntiy searchObj = new StudentInfoEntiy(); searchObj.ProfessionID = int.Parse(this.cmbPro.SelectedValue.ToString()); searchObj.StuName = this.txtName.Text; this.dataGridView1.AutoGenerateColumns = false; this.dataGridView1.DataSource = stuBll.Search(searchObj); } #endregion #region 窗體加載 private void FrmSelect_Load(object sender, EventArgs e) { BindPro(); BindData(); } #endregion #region 搜索按鈕 private void btSearch_Click(object sender, EventArgs e) { BindData(); } #endregion
(4)刪除菜單代碼:
private void 刪除ToolStripMenuItem_Click(object sender, EventArgs e) { //添加是否確定刪除的對話框 DialogResult result = MessageBox.Show("確定要刪除數(shù)據(jù)嗎,刪除之后無法恢復(fù)!", "提示框", MessageBoxButtons.OKCancel, MessageBoxIcon.Question); if (result == DialogResult.Cancel) return; string stuid = this.dataGridView1.SelectedRows[0].Cells[0].Value.ToString(); if(stuBll.Delete(stuid) == 1) MessageBox.Show("刪除成功!"); else MessageBox.Show("刪除失敗!"); BindData(); }
新增窗體界面及代碼:
ProfessionInfoBLL proBll = new ProfessionInfoBLL(); StudentInfoBLL stuBll = new StudentInfoBLL(); #region 綁定下拉框 private void BindPro() { List<ProfessionInfoEntity> list = new List<ProfessionInfoEntity>(); list = proBll.List(); list.Insert(0, new ProfessionInfoEntity { ProfessionID = 0, ProfessionName = "--請選擇--" }); this.cmbPro.DataSource = list; this.cmbPro.DisplayMember = "ProfessionName"; this.cmbPro.ValueMember = "ProfessionID"; } #endregion private void FrmAdd_Load(object sender, EventArgs e) { BindPro(); } private void btAdd_Click(object sender, EventArgs e) { //性別處理 string sex = ""; if (this.rbBoy.Checked == true) sex = this.rbBoy.Text; if (this.rbGirl.Checked == true) sex = this.rbGirl.Text; //愛好處理 string hobby = ""; foreach (CheckBox ck in this.panel2.Controls) { if (ck.Checked == true) { if (!hobby.Equals("")) hobby += ","; hobby += ck.Text; } } StudentInfoEntiy entity = new StudentInfoEntiy(); entity.StuID = this.txtId.Text; entity.StuName = this.txtName.Text; entity.StuAge = int.Parse(this.txtAge.Text); entity.StuSex = sex; entity.StuHobby = hobby; entity.ProfessionID = int.Parse(this.cmbPro.SelectedValue.ToString()); if (stuBll.Add(entity) == 1) MessageBox.Show("新增成功!"); else MessageBox.Show("新增失敗!"); this.Close(); }
編輯修改窗體界面及代碼:
public string StuID { get; set; } //學(xué)生編號 ProfessionInfoBLL proBll = new ProfessionInfoBLL(); StudentInfoBLL stuBll = new StudentInfoBLL(); #region 綁定下拉框 private void BindPro() { List<ProfessionInfoEntity> list = new List<ProfessionInfoEntity>(); list = proBll.List(); list.Insert(0, new ProfessionInfoEntity { ProfessionID = 0, ProfessionName = "--請選擇--" }); this.cmbPro.DataSource = list; this.cmbPro.DisplayMember = "ProfessionName"; this.cmbPro.ValueMember = "ProfessionID"; } #endregion #region 綁定詳情 private void BindDetail() { StudentInfoEntiy entity = new StudentInfoEntiy(); entity = stuBll.Detail(this.StuID); this.txtId.Text = entity.StuID; this.txtName.Text = entity.StuName; this.txtAge.Text = entity.StuAge.ToString(); this.cmbPro.SelectedValue = entity.ProfessionID; //性別處理 if (entity.StuSex.Equals("男")) this.rbBoy.Checked = true; else this.rbGirl.Checked = true; //愛好處理 string[] arrHobby = entity.StuHobby.Split(','); foreach (string hobby in arrHobby) { foreach (CheckBox ck in this.panel2.Controls) { if (ck.Text.Equals(hobby)) ck.Checked = true; } } } #endregion private void FrmEdit_Load(object sender, EventArgs e) { BindPro(); BindDetail(); } private void btUpdate_Click(object sender, EventArgs e) { //性別處理 string sex = ""; if (this.rbBoy.Checked == true) sex = this.rbBoy.Text; if (this.rbGirl.Checked == true) sex = this.rbGirl.Text; //愛好處理 string hobby = ""; foreach (CheckBox ck in this.panel2.Controls) { if (ck.Checked == true) { if (!hobby.Equals("")) hobby += ","; hobby += ck.Text; } } StudentInfoEntiy entity = new StudentInfoEntiy(); entity.StuID = this.txtId.Text; entity.StuName = this.txtName.Text; entity.StuAge = int.Parse(this.txtAge.Text); entity.StuSex = sex; entity.StuHobby = hobby; entity.ProfessionID = int.Parse(this.cmbPro.SelectedValue.ToString()); if (stuBll.Update(entity) == 1) MessageBox.Show("修改成功!"); else MessageBox.Show("修改失敗!"); this.Close(); }
查詢窗體中"新增"和"編輯"按鈕代碼:
private void btAdd_Click(object sender, EventArgs e) { FrmAdd frm = new FrmAdd(); frm.Show(); } private void btEdit_Click(object sender, EventArgs e) { string stuid = this.dataGridView1.SelectedRows[0].Cells[0].Value.ToString(); FrmEdit frm = new FrmEdit(); frm.StuID = stuid; frm.Show(); }
到此這篇關(guān)于C#使用三層架構(gòu)開發(fā)Winform的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#調(diào)用dll報錯:無法加載dll,找不到指定模塊的解決
這篇文章主要介紹了C#調(diào)用dll報錯:無法加載dll,找不到指定模塊的解決問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01WinForm下 TextBox只允許輸入數(shù)字的小例子
WinForm下 TextBox只允許輸入數(shù)字的小例子,需要的朋友可以參考一下2013-04-04C# Oracle批量插入數(shù)據(jù)進度條的實現(xiàn)代碼
這篇文章主要介紹了C# Oracle批量插入數(shù)據(jù)進度條的實現(xiàn)代碼,需要的朋友可以參考下2018-04-04c#?Task.Wait()與awaiat?Task異常處理的區(qū)別說明
這篇文章主要介紹了c#?Task.Wait()與awaiat?Task異常處理的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06C#中Activator.CreateInstance()方法用法分析
這篇文章主要介紹了C#中Activator.CreateInstance()方法用法,實例分析了C#中Activator.CreateInstance()方法的功能、定義及使用技巧,需要的朋友可以參考下2015-03-03C#中將DataTable轉(zhuǎn)化成List<T>的方法解析
大家應(yīng)該都知道在.net項目中使用到DataTable和List<T>集合的地方較多,有的時候需要將DataTable轉(zhuǎn)化成List<T>,那么改如何轉(zhuǎn)化呢?下面通過這篇文章來一起學(xué)習(xí)下吧,本文中給出了詳細(xì)的示例代碼,相信對大家的理解和學(xué)習(xí)具有一定的參考借鑒價值。2016-12-12