三層架構(gòu)是一種常用的軟件開(kāi)發(fā)架構(gòu)模式,它將應(yīng)用程序分為三個(gè)層次:表示層、業(yè)務(wù)邏輯層和數(shù)據(jù)訪問(wèn)層。每一層都有明確的職責(zé)和功能,分別負(fù)責(zé)用戶交互、業(yè)務(wù)處理和數(shù)據(jù)存儲(chǔ)等任務(wù)。這種架構(gòu)模式的優(yōu)點(diǎn)包括易于維護(hù)和擴(kuò)展、更好的組織結(jié)構(gòu)和代碼重用性、更高的安全性等方面。在具體實(shí)現(xiàn)中,需要根據(jù)不同的應(yīng)用程序需求和技術(shù)平臺(tái)選擇適當(dāng)?shù)墓ぞ吆涂蚣?,以達(dá)到最佳的開(kāi)發(fā)效果和應(yīng)用程序質(zhì)量。
?
在 .NET 中,我們同樣可以使用三層架構(gòu)來(lái)構(gòu)建我們的應(yīng)用程序,實(shí)現(xiàn)表示層、業(yè)務(wù)邏輯層和數(shù)據(jù)訪問(wèn)層的分離。下面分別介紹在 .NET 中如何實(shí)現(xiàn)這三層架構(gòu)。
????????1.表示層
在 .NET 中,我們可以使用 WinForms、WPF、ASP.NET 等技術(shù)來(lái)實(shí)現(xiàn)表示層的功能。在 WinForms 和 WPF 中,我們可以使用各種控件來(lái)構(gòu)建用戶界面,以顯示和收集數(shù)據(jù)。在 ASP.NET 中,我們可以使用 ASP.NET Web 窗體、MVC、Web API 等技術(shù)來(lái)生成和管理 Web 頁(yè)面。
在所有情況下,表示層的主要職責(zé)是接收用戶輸入和顯示數(shù)據(jù)。例如,在 WinForms 中,我們可以使用窗體和控件來(lái)表示 UI,并通過(guò)事件處理程序和數(shù)據(jù)綁定來(lái)響應(yīng)用戶輸入和顯示數(shù)據(jù)。在 ASP.NET 中,我們可以使用代碼片段來(lái)生成 HTML、CSS 和 JavaScript,并使用服務(wù)器端腳本和控件來(lái)處理事件和數(shù)據(jù)綁定。
????????2.業(yè)務(wù)邏輯層
在 .NET 中,我們可以使用類和接口來(lái)實(shí)現(xiàn)業(yè)務(wù)邏輯層。這些類和接口通常包括與應(yīng)用程序相關(guān)的業(yè)務(wù)邏輯和規(guī)則,例如驗(yàn)證、授權(quán)、計(jì)算和處理數(shù)據(jù)。
業(yè)務(wù)邏輯層通常向表示層公開(kāi) API,以便 UI 可以與業(yè)務(wù)邏輯進(jìn)行交互。例如,在 ASP.NET MVC 中,我們可以使用控制器和模型來(lái)處理請(qǐng)求,并使用視圖來(lái)處理 UI。在 WinForms 中,我們通常將業(yè)務(wù)邏輯封裝在一個(gè)專用的類或類庫(kù)中,并使用事件處理程序和數(shù)據(jù)綁定來(lái)處理 UI。
????????3.數(shù)據(jù)訪問(wèn)層
在 .NET 中,我們可以使用 ADO.NET 和 Entity Framework 來(lái)訪問(wèn)數(shù)據(jù)。ADO.NET 提供了一組用于連接到和操作關(guān)系型數(shù)據(jù)庫(kù)的類和接口,而 Entity Framework 則提供了一種對(duì)象關(guān)系映射(ORM)框架,使我們可以將對(duì)象與數(shù)據(jù)庫(kù)記錄進(jìn)行映射和交互。
數(shù)據(jù)訪問(wèn)層通常會(huì)使用一些技術(shù)和工具來(lái)管理和維護(hù)數(shù)據(jù),例如 SQL Server Management Studio 或 LINQ。我們可以使用 ADO.NET 和 Entity Framework 來(lái)執(zhí)行數(shù)據(jù)庫(kù)操作,并使用倉(cāng)儲(chǔ)模式或 DAL 等設(shè)計(jì)模式來(lái)創(chuàng)建底層數(shù)據(jù)庫(kù)連接和訪問(wèn)代碼。
?下面通過(guò)一個(gè)簡(jiǎn)易的例題來(lái)演示三層架構(gòu)的簡(jiǎn)易模式:
- 首先建立一個(gè)數(shù)據(jù)庫(kù)(EmployeeSystem)
- 內(nèi)部包含兩個(gè)表(AdminInfo),(EmployeeInfo)
- AdminInfo表(登錄驗(yàn)證表)包含兩字段:主鍵:Account(varchar)用戶名,Pwd(varchar) 密碼? 用于登錄驗(yàn)證
- EmployeeInfo表(學(xué)生信息表)包含六個(gè)字段 :主鍵自增列:Id(int)編號(hào),EmployeeName (varchar)? 姓名,EmployeeNo(varchar)學(xué)號(hào),EmployeeAge(int?)年齡,EmployeeSalary(int)就業(yè)工資,EmployeeJob(varchar)職業(yè)名稱
? 以上完成了示例數(shù)據(jù)庫(kù)的搭建?
接下來(lái)打開(kāi)Microsoft Visual Studio2022,開(kāi)始新建項(xiàng)目
?
- ?在解決方案里創(chuàng)建一個(gè)Windows窗體應(yīng)用程序取名UI作為我們這個(gè)項(xiàng)目的表示層
- 在解決方案里添加三個(gè)類庫(kù)
- Model 模型層主要包含一些數(shù)據(jù)庫(kù)中表對(duì)應(yīng)的實(shí)體類,作為數(shù)據(jù)傳遞的載體
- DAL? 數(shù)據(jù)訪問(wèn)層 :與數(shù)據(jù)庫(kù)進(jìn)行交互 執(zhí)行增刪改查的操作
- BLL 業(yè)務(wù)邏輯層:對(duì)業(yè)務(wù)邏輯進(jìn)行處理 ,比如進(jìn)行判斷(必要的非空判斷,添加前是否已經(jīng)存在同樣的數(shù)據(jù))
?
????????6.打開(kāi)UI找到引用:
?第2步:定義連接字符串
? ? ? ? name 屬性是用于標(biāo)識(shí)連接字符串的名稱的字符串。
? ? ? ? connectionString 是數(shù)據(jù)庫(kù)連接時(shí)用到的字符串。
?????????providerName 屬性是用于指定數(shù)據(jù)提供程序的名稱字符串。它通常與 connectionString 屬性一起使用,來(lái)告訴應(yīng)用程序要使用哪個(gè)特定的 ADO.NET 數(shù)據(jù)提供程序來(lái)訪問(wèn)數(shù)據(jù)庫(kù)。
最后再到UI層
?
?到這里了接下來(lái)進(jìn)入Model層
?我們首先從模型層開(kāi)始寫(xiě):
這里類里添加了兩個(gè)類分別對(duì)應(yīng)數(shù)據(jù)庫(kù)里的兩張表以及各字段?
到這個(gè)模型層算搭建完(記得把修飾符改成公有的)
?下一步給各層設(shè)置相互之間的引用
- ?UI表示層需要引用BLL業(yè)務(wù)邏輯層和Model模型層
- DAL數(shù)據(jù)訪問(wèn)層需要引入Model模型層
- BLL業(yè)務(wù)邏輯層需要引入DAL數(shù)據(jù)訪問(wèn)層和Model模型層
?到這個(gè)項(xiàng)目的引用關(guān)系也就完事了
接下來(lái)就可以開(kāi)始著手DAL數(shù)據(jù)訪問(wèn)層的內(nèi)容了
DAL 層中的 SqlHelper 方法通常被稱為數(shù)據(jù)訪問(wèn)助手方法(Data Access Helper Method),它們主要用于將應(yīng)用程序的業(yè)務(wù)邏輯和底層數(shù)據(jù)訪問(wèn)邏輯分離開(kāi)來(lái)。
通常情況下,SqlHelper 方法都包裝了底層 ADO.NET API,以提供更簡(jiǎn)單、更易用的 API 接口,從而幫助開(kāi)發(fā)人員更輕松地訪問(wèn)數(shù)據(jù)庫(kù)。這些方法通常包括執(zhí)行 SQL 語(yǔ)句、存儲(chǔ)過(guò)程的方法,還有獲取數(shù)據(jù)表、數(shù)據(jù)集等返回值的方法。
SqlHelper 方法可以接受連接字符串、SQL 語(yǔ)句、存儲(chǔ)過(guò)程名稱以及參數(shù)等信息作為參數(shù),并使用它們來(lái)構(gòu)建和執(zhí)行數(shù)據(jù)庫(kù)操作。通過(guò)將這些詳細(xì)信息隱藏在方法內(nèi)部,SqlHelper 方法幫助程序員簡(jiǎn)化了代碼邏輯,提高了代碼結(jié)構(gòu)的清晰度和可讀性。同時(shí),SqlHelper 方法還可以處理數(shù)據(jù)庫(kù)連接、異常處理等底層邏輯,從而提高了數(shù)據(jù)訪問(wèn)代碼的可靠性和穩(wěn)定性。
需要注意的是,不同的數(shù)據(jù)訪問(wèn)技術(shù)和開(kāi)發(fā)框架通常有不同的 SqlHelper 實(shí)現(xiàn)方式,例如在 ASP.NET 中,我們通常使用 SqlHelper 類來(lái)訪問(wèn) SQL Server 數(shù)據(jù)庫(kù),而在 Entity Framework 中,我們可以使用 DbContext 來(lái)管理數(shù)據(jù)訪問(wèn)邏輯,或者使用 LINQ 表達(dá)式來(lái)查詢數(shù)據(jù)。
- ?建立一個(gè)公有,靜態(tài)類SqlHelper (內(nèi)部方法也均為公有靜態(tài)方法)
static readonly string ido= ConfigurationManager.ConnectionStrings["配置文件內(nèi)add里的name名"].ToString();
//這段代碼的作用是從應(yīng)用程序配置文件 (App.config) 中獲取名為 “配置文件內(nèi)add里的name名” 的連接字符串,并將其存儲(chǔ)在一個(gè)名為 “ido” 的靜態(tài)只讀字符串常量 ido 中。
?????2.接下來(lái)寫(xiě)下兩個(gè)方法
? ? ? ? 思路:根據(jù)執(zhí)行數(shù)據(jù)庫(kù)增刪改查操作的返回值來(lái)分類方法
? ? ? ? ? ? ? ? ? ? ? ? 1.查詢操作返回的是DataTable 是一個(gè) C# 中的數(shù)據(jù)表格類,它代表了一個(gè)內(nèi)存中的數(shù)據(jù)表格,提供了一種方便的方法來(lái)存儲(chǔ)和操作數(shù)據(jù)。
? ? ? ? ? ? ? ? ? ? ? ? 2.增刪改操作的不同點(diǎn)只是sql語(yǔ)句有差異,他們共同點(diǎn)的返回類型都是受影響的行數(shù)。
? ? ? ? ? ? ? ? ? ? ? ? 3.由此存在了兩種返回類型的值,可以在擬定兩個(gè)返回值類型的方法分別為int和DataTable
? ?3.查詢表值的方法返回DAtaTable
public static DataTable selectall(string sql)
{
//建立數(shù)據(jù)庫(kù)連接 App.config里準(zhǔn)備的數(shù)據(jù)庫(kù)連接語(yǔ)句在這個(gè)時(shí)候可以體現(xiàn)用處了
SqlConnection conn = new SqlConnection(ido);
//打開(kāi)數(shù)據(jù)庫(kù)連接
conn.Open();
// 創(chuàng)建數(shù)據(jù)適配器對(duì)象
SqlDataAdapter ter = new SqlDataAdapter(sql, conn);
//實(shí)例化DataTable
DataTable dt = new DataTable();
// 使用數(shù)據(jù)適配器填充數(shù)據(jù)集
ter.Fill(dt);
//關(guān)閉數(shù)據(jù)庫(kù)連接
conn.Close();
//返回值
return dt;
}
???4.增刪改的方法返回受影響行數(shù)
public static int CUD(string sql)
{
SqlConnection conn = new SqlConnection(ido);
conn.Open();
//創(chuàng)建sql命令對(duì)象
SqlCommand com= new SqlCommand(sql,conn);
//用一個(gè)int 變量來(lái)接收受影響的返回行數(shù)
int r=com.ExecuteNonQuery();
//返回r的值
return r;
}
? ?5.參數(shù)化命令的增刪改方法
public static bool selectal(string sql,List<SqlParameter> list)
{
SqlConnection conn = new SqlConnection(ido);
conn.Open();
SqlCommand com = new SqlCommand(sql, conn);
//使用 AddRange 方法一次性添加多個(gè) SqlParameter 對(duì)象,list需要轉(zhuǎn)換成數(shù)組添加
com.Parameters.AddRange(list.ToArray());
//接收?qǐng)?zhí)行查詢時(shí)返回的結(jié)果集中第一行第一列的值如果有數(shù)據(jù)就會(huì)大于0
int r = Convert.ToInt32(com.ExecuteScalar());
//判斷r的值來(lái)決定返回的bool
if(r >0) { return true; } else { return false; }
}
到這一步數(shù)據(jù)訪問(wèn)助手的類已經(jīng)完成了
DAL 數(shù)據(jù)訪問(wèn)層再為每張表定義一個(gè)類調(diào)用數(shù)據(jù)訪問(wèn)助手(在這里可以寫(xiě)入你需要執(zhí)行的sql語(yǔ)句操作)
首先我們來(lái)做最簡(jiǎn)單的AdminInfo表(登錄驗(yàn)證表)做執(zhí)行一個(gè)登錄的查詢操作
? ? ? ? 這里需要主要預(yù)防sql注入攻擊,所以要采用參數(shù)化命令的方法
?在DAL層創(chuàng)建一個(gè)AdmDAL類調(diào)用SqlHelper類的方法
//參數(shù)為AdminInfo類
public bool admopen(AdminInfo info)
{
//sql語(yǔ)句
string sql = "select count(*) from AdminInfo where Account=@Account and Pwd=@Pwd";
//創(chuàng)建了一個(gè) List<SqlParameter> 實(shí)例,用于存儲(chǔ)多個(gè) SqlParameter 對(duì)象。然后通過(guò)調(diào)用 List<T> 對(duì)象的 Add 方法向集合添加一個(gè)參數(shù),或使用 AddRange 方法一次添加多個(gè)參數(shù)
List<SqlParameter> list= new List<SqlParameter>();
list.Add(new SqlParameter("@Account", info.Account));
list.Add(new SqlParameter("@Pwd", info.Pwd));
//返回值調(diào)用SqlHelper的方法(傳入sql語(yǔ)句和參數(shù)化命令對(duì)象的值)最終返回一個(gè)bool類型的值
return SqlHelper.selectal(sql, list);
}
DAL層最后一個(gè)類EmpADL類?EmployeeInfo表(學(xué)生信息表)的各項(xiàng)操作
全部采取的sqlHelper的方法
簡(jiǎn)易的只需要寫(xiě)一條sql語(yǔ)句再返回調(diào)用方法(傳入string sql語(yǔ)句參數(shù))
有參數(shù)化命令的方法就根據(jù)sql語(yǔ)句創(chuàng)建一個(gè)list集合來(lái)存儲(chǔ)方法類的值再返回參數(shù)化命令方法(sql語(yǔ)句,list集合)
//添加學(xué)生的方法
public int EmpInsert(EmployeeInfo info)
{
string sql = "insert into EmployeeInfo values(@EmployeeName,@EmployeeNo,@EmployeeAge,@EmployeeSalary,@EmployeeJob)";
List<SqlParameter> list = new List<SqlParameter>();
list.Add(new SqlParameter("@EmployeeName", info.EmployeeName));
list.Add(new SqlParameter("@EmployeeNo", info.EmployeeNo));
list.Add(new SqlParameter("@EmployeeAge", info.EmployeeAge));
list.Add(new SqlParameter("@EmployeeSalary", info.EmployeeSalary));
list.Add(new SqlParameter("@EmployeeJob", info.EmployeeJob));
return SqlHelper.CUD(sql, list);
}
//修改方法
public int EmpUpdate(EmployeeInfo info)
{
string sql = "update EmployeeInfo set EmployeeName=@EmployeeName,EmployeeNo=@EmployeeNo,EmployeeAge=@EmployeeAge,EmployeeSalary=@EmployeeSalary,EmployeeJob=@EmployeeJob where Id=@Id";
List<SqlParameter> list = new List<SqlParameter>();
list.Add(new SqlParameter("@EmployeeName", info.EmployeeName));
list.Add(new SqlParameter("@EmployeeNo", info.EmployeeNo));
list.Add(new SqlParameter("@EmployeeAge", info.EmployeeAge));
list.Add(new SqlParameter("@EmployeeSalary", info.EmployeeSalary));
list.Add(new SqlParameter("@EmployeeJob", info.EmployeeJob));
list.Add(new SqlParameter("@Id", info.Id));
return SqlHelper.CUD(sql, list);
}
//刪除方法
public int EmpDelete(int id)
{
string sql = $"delete from EmployeeInfo where Id={id}";
return SqlHelper.CUD(sql);
}
//查詢整表的方法
public DataTable select()
{
string sql = "select * from EmployeeInfo";
return SqlHelper.selectall(sql);
}
//根據(jù)編號(hào)查詢的方法
public DataTable selectID(int id) {
string sql = $"select * from EmployeeInfo where Id={id}";
return SqlHelper.selectall(sql);
}
//根據(jù)姓名模糊查詢的方法
public DataTable SelectName(string name) {
string sql = $"select * from EmployeeInfo where EmployeeName like '%{name}%'";
return SqlHelper.selectall(sql);
}
以上這些就是DAL 數(shù)據(jù)訪問(wèn)層的基本方法 如果有額外的需求的話可以根據(jù)個(gè)人的要求結(jié)合所學(xué)的知識(shí)再去新建方法體
下面我們?cè)賮?lái)到BLL業(yè)務(wù)邏輯層
業(yè)務(wù)邏輯層需要做什么呢?
簡(jiǎn)單的來(lái)講就是連接UI表示層和DAL數(shù)據(jù)訪問(wèn)層的橋梁,在這里會(huì)對(duì)數(shù)據(jù)進(jìn)行一些加工例如判斷數(shù)據(jù)是否為空等等,該怎么做需要屏幕前的你來(lái)發(fā)揮了
下面來(lái)看示例
public class EmpBLL
{
//實(shí)例化DAL數(shù)據(jù)訪問(wèn)層的EmpDAL類 并用方法調(diào)用EMpDAL類的方法
private EmpDAL EmpDAL = new EmpDAL();
//添加的方法
public int EmpInsert(EmployeeInfo info)
{
return EmpDAL.EmpInsert(info);
}
//修改的方法
public int EmpUpdate(EmployeeInfo info)
{
return EmpDAL.EmpUpdate(info);
}
//刪除的方法
public int EmpDelete(int id)
{
return EmpDAL.EmpDelete(id);
}
//查詢整表的方法
public DataTable select()
{
return EmpDAL.select();
}
//根據(jù)姓名模糊查詢的方法
public DataTable SelectName(string name)
{
return EmpDAL.SelectName(name);
}
//根據(jù)編號(hào)查詢的方法
public DataTable SelectID(int id)
{
return EmpDAL.selectID(id);
}
以上是EmployeeInfo學(xué)生信息表需要在表示層使用的方法
接下來(lái)是AdminInfo登錄信息表需要的業(yè)務(wù)邏輯層方法
public class AdmBLL
{
//實(shí)例化數(shù)據(jù)訪問(wèn)層的AdmDAL類 并調(diào)用方法
private AdmDAL AdmDAL=new AdmDAL();
//登錄方法
public bool admopen(AdminInfo info)
{
return AdmDAL.admopen(info);
}
}
到這里業(yè)務(wù)邏輯層也就完工了
最后一個(gè)UI 表示層 使用WinForms窗體應(yīng)用程序搭建
首先完成一個(gè)簡(jiǎn)易的登錄操作
在UI層建立一個(gè)窗體form1?
使用控件 label* 2 ,textbox*2 button*1
?給窗體登錄按鈕 雙擊添加點(diǎn)擊事件
private void button1_Click(object sender, EventArgs e)
{
//實(shí)例化模型層Model 的AdminInfo類 并把文本框的值賦給里面的字段
AdminInfo info= new AdminInfo();
info.Account = textBox1.Text;
info.Pwd= textBox2.Text;
//實(shí)例化BLL 業(yè)務(wù)邏輯層調(diào)用相對(duì)應(yīng)的方法
AdmBLL adm= new AdmBLL();
//定義一個(gè)bool值的變量來(lái)接收返回值
bool f= adm.admopen(info);
//通過(guò)判斷f的值來(lái)選擇執(zhí)行的操作,為true則彈窗登錄成功并打開(kāi)后續(xù)的窗體
if (f==true)
{
MessageBox.Show("登錄成功");
Form2 form2 = new Form2();
form2.Show();
}
else { MessageBox.Show("登錄失敗"); }
}
最后再給UI表示層添加一個(gè)form2窗體用于示例DAL和BLL的方法
為了簡(jiǎn)易采用dategridview
?上面的窗體我們添加了多個(gè)按鈕
先從窗體的加載事件開(kāi)始,首先在窗體內(nèi)部添加一個(gè)公有的BLL業(yè)務(wù)邏輯層的實(shí)例對(duì)象,便于調(diào)用其方法。
public EmpBLL empBLL = new EmpBLL();//實(shí)例化業(yè)務(wù)邏輯層
//初始化dategridview的表值
//將方法放入form2_load窗體加載事件中即可初始化值
public void select()
{
dataGridView1.DataSource = empBLL.select();//調(diào)用業(yè)務(wù)邏輯層查詢整表的方法加載到datagridview控件中
dataGridView1.ClearSelection();//取消默認(rèn)選中狀態(tài)
}
刪除按鈕:button2
//刪除按鈕點(diǎn)擊事件
private void button2_Click(object sender, EventArgs e)
{
//對(duì)datagridview的選中項(xiàng)進(jìn)行判斷,未選中行時(shí)彈窗提示
if (dataGridView1.SelectedRows.Count<=0)
{
MessageBox.Show("請(qǐng)選中你需要?jiǎng)h除的一行!");
}
else if (dataGridView1.SelectedRows.Count > 0)
{
//獲取選中行的第一行第一列的值用 一個(gè)int的變量來(lái)接收方便調(diào)用后續(xù)的業(yè)務(wù)邏輯層刪除的方法
int id = Convert.ToInt32(this.dataGridView1.SelectedRows[0].Cells[0].Value);
//接收刪除方法的返回值進(jìn)行受影響的行判斷
int i = empBLL.EmpDelete(id);
if (i > 0)
{
//刪除成功時(shí)彈窗提示并調(diào)用給datagridview賦值的方法(select())
MessageBox.Show("刪除成功");
select();
}
else { MessageBox.Show("刪除失敗"); }
}
}
添加的按鈕:button1
private void button1_Click(object sender, EventArgs e)
{
//設(shè)置跳轉(zhuǎn)到目標(biāo)窗體并設(shè)置父子級(jí)
Form3 form3 = new Form3();
form3.Owner= this;
form3.Show();
}
form3窗體如下:
注:編號(hào)Id為自增列,所有只有五個(gè)字段
?這里只需要為添加按鈕添加點(diǎn)擊事件:
//添加按鈕點(diǎn)擊事件
private void button1_Click(object sender, EventArgs e)
{
//實(shí)例化EmployeeInfo類
EmployeeInfo info = new EmployeeInfo();
info.EmployeeName=textBox1.Text;
info.EmployeeNo=textBox2.Text;
info.EmployeeAge=int.Parse(textBox3.Text);
info.EmployeeSalary=int.Parse(textBox4.Text);
info.EmployeeJob=textBox5.Text;
//給類中的每個(gè)字段賦值
EmpBLL empBLL = new EmpBLL();
//實(shí)例化BLL業(yè)務(wù)邏輯層的EmpBLL方法類,調(diào)用其中的添加方法把info作為參數(shù)傳入
int r= empBLL.EmpInsert(info);
//用變量接收返回值來(lái)判斷受影響行數(shù)
if (r > 0) {
MessageBox.Show("添加成功");
Form2 form=this.Owner as Form2;
form.select();
this.Close();
} else { MessageBox.Show("添加失敗"); }
}
Form2 form=this.Owner as Form2:
這段的理解是:將當(dāng)前窗體的擁有者窗體轉(zhuǎn)換為 Form2 類型,并將轉(zhuǎn)換后的實(shí)例賦值給了 form 變量。這樣,我們就可以直接訪問(wèn)該窗體對(duì)象的屬性和方法,例如 form 屬性或者 Show 方法等。需要注意的是,如果 this.Owner 不是 Form2 類型的對(duì)象,則 form 變量將為 null。
之后再調(diào)用form2窗體的select()方法實(shí)現(xiàn)添加成功之后刷新form2的datagridview的集合
剩余的幾個(gè)按鈕就不一一進(jìn)行講解了,原理同上,有時(shí)間可以自己多練習(xí)熟能生巧,該文章只供參考用于理解軟件開(kāi)發(fā)模式的三層架構(gòu),相信認(rèn)真看了的小伙伴能夠看出對(duì)于傳統(tǒng)的一個(gè)控件一個(gè)控件來(lái)完善的方式節(jié)省的代碼量是非??捎^的。
最后文章到這里就結(jié)束了,如果感覺(jué)對(duì)你有幫助的話可以點(diǎn)贊或收藏來(lái)加深理解。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-494790.html
再感謝認(rèn)真看完文章的人對(duì)我的認(rèn)可,本人會(huì)持續(xù)更新更多對(duì)粉絲有用的文章喜歡的可以關(guān)注支持哦文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-494790.html
到了這里,關(guān)于.net 軟件開(kāi)發(fā)模式——三層架構(gòu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!