黑馬程式設計師 C#學習筆記⑥ 三層架構基礎實現員工資訊管理
三層架構定義
1、表現層(UIL):通俗講就是展現給使用者的介面,即使用者在使用一個系統的時候他的所見所得。
2、業務邏輯層(BLL):針對具體問題的操作,也可以說是對資料層的操作,對資料業務邏輯處理。
3、資料訪問層(DAL):該層所做事務直接操作資料庫,針對資料的增添、刪除、修改、查詢等。
在本程式中使用了DAL層和UI層
在CustomerDAL需要包括一系列的方法
GetById ()
Update()
DeleteById()
GetAll ()
GetPageData()
Insert()
使用簡單的三層架構實現一個員工資訊管理
先在資料庫中建立一個T_Customers的表
列名稱 |
型別 |
Id |
bigint |
Name |
nvarchar(50) |
Birthday |
Datetime |
Address |
Nvarchar(50) |
TelNum |
Nvarchar(50) |
CustLevel |
Nchar(5) |
如果含有可空型別的話,就需要在傳入或者傳出值的時候呼叫ToDBValue或者FromDBValue方法
Birthday可空在C#中型別為datetime?
建立Model資料夾, 在資料夾中新增可以用來儲存值的Customer類
namespace 三層架構基礎.Model
{
public class Customer
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime? Birthday { get; set; }
public string Address { get; set; }
public string TelNum { get; set; }
public string CustLevel { get; set; }
}
}
建立DAL資料夾, 在其中建立需要用到的SqlHelper類和CustomerDAL類
CustomerDAL類中定義如下方法:
GetAll() |
返回型別Customer[], 其中存放了表中所有資訊 |
GetById(long Id) |
通過Id查詢, 返回查到的結果, 返回型別Customer |
Insert(Customer cust) |
向表中插入cust物件 |
DeleteById(long Id) |
通過Id刪除 |
Update(Customer cust) |
使用傳入的cust物件更新原資訊 |
using System;
usingSystem.Collections.Generic;
using System.Data;
usingSystem.Data.SqlClient;
using System.Linq;
using System.Text;
usingSystem.Threading.Tasks;
using 三層架構基礎.Model;
namespace三層架構基礎
{
public class CustomerDAL
{
//根據Id獲取GetById Update DeleteById GetAllGetPageData
//Insert(Customer cust)
public Customer GetById(long Id)
{
DataTable dt =SqlHelper.ExecuteDataSet("Select * from T_Customers where [email protected]",
newSqlParameter("@Id", Id));
//對返回結果進行判斷
if (dt.Rows.Count <= 0)
{
return null;
}
else if (dt.Rows.Count > 1)
{
throw newException("資料重複, 發生錯誤");
}
else
{
DataRow row = dt.Rows[0];
//Customer cust = newCustomer();
//cust.Id =(long)row["Id"];
//cust.Name =(string)row["Name"];
//cust.Birthday =(DateTime?)row["Birthday"];
//cust.Address =(string)row["Address"];
//cust.TelNum =(string)row["TelNum"];
//cust.CustLevel =(char)row["CustLevel"];
return ToCustomer(row);
}
}
public void DeleteById(long Id)
{
SqlHelper.ExecuteNonQuery("Delete from T_Customers [email protected]",
newSqlParameter("@Id", Id));
}
public void Insert(Customer cust)
{
SqlHelper.ExecuteNonQuery(@"INSERT INTO [T_Customers]
([Name]
,[Birthday]
,[Address]
,[TelNum]
,[CustLevel])
VALUES
(@Name,
@Birthday,
@Address,
@TelNum,
@CustLevel)",
newSqlParameter("@Name", cust.Name),
newSqlParameter("@Birthday", SqlHelper.ToDbValue(cust.Birthday)),
newSqlParameter("@Address", cust.Address),
newSqlParameter("@TelNum", cust.TelNum),
newSqlParameter("@CustLevel", cust.CustLevel));
}
public void Update(Customer cust)
{
SqlHelper.ExecuteNonQuery(@"Update [T_Customers]
Set[Name][email protected]
,[Birthday][email protected]
,[Address][email protected]
,[TelNum][email protected]
,[CustLevel][email protected]
newSqlParameter("@Name", cust.Name),
newSqlParameter("@Birthday", SqlHelper.ToDbValue(cust.Birthday)),
newSqlParameter("@Address", cust.Address),
newSqlParameter("@TelNum", cust.TelNum),
newSqlParameter("@CustLevel", cust.CustLevel),
newSqlParameter("@Id", cust.Id));
}
public Customer[] GetAll()
{
DataTable dt =SqlHelper.ExecuteDataSet("Select * from T_Customers");
Customer[] customers = newCustomer[dt.Rows.Count];
//使用迴圈遍歷table中的查詢結果(dt.Rows集合), 然後轉換成
//Customer型別, 存到customers陣列中.
for (int i = 0; i <dt.Rows.Count; i++)
{
DataRow row = dt.Rows[i];
customers[i] = ToCustomer(row);
}
return customers;
}
//將DataRow型別轉換成Customer型別
private Customer ToCustomer(DataRowrow)
{
Customer cust = new Customer();
cust.Id =(long)row["Id"];
cust.Name =(string)row["Name"];
cust.Birthday =(DateTime?)SqlHelper.FromDbValue(row["Birthday"]);
cust.Address =(string)row["Address"];
cust.TelNum =(string)row["TelNum"];
cust.CustLevel =(string)row["CustLevel"];
return cust;
}
}
}
需要注意的地方就是在Insert和Update方法中, 傳入Birthday值的時候需要ToDbValue方法轉換值, 同理在ToCustomer方法中, 需要呼叫FromDbValue方法
UI層
CustomerListUI和CustomerEditUI
CustomerListUI
<Window x:Class="三層架構基礎.CustomerListUI"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CustomerListUI"Height="300" Width="800"
WindowState="Maximized"ResizeMode="NoResize" Loaded="Window_Loaded_1">
<Grid>
<DockPanel>
<ToolBar Height="30"DockPanel.Dock="Top">
<Buttonx:Name="btnAdd" Margin="0,2,0,1"VerticalAlignment="Stretch" Click="btnAdd_Click">新增</Button>
<Buttonx:Name="btnEdit" Click="btnEdit_Click">修改</Button>
<Buttonx:Name="btnDelete" Margin="0,0,0,1"VerticalAlignment="Bottom" Click="btnDelete_Click">刪除</Button>
</ToolBar>
<DataGridx:Name="grid" DockPanel.Dock="Top"IsReadOnly="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="姓名"Width="100" Binding="{BindingName}"></DataGridTextColumn>
<DataGridTextColumn Header="生日"Width="100" Binding="{BindingBirthday}"></DataGridTextColumn>
<DataGridTextColumn Header="電話"Width="100" Binding="{BindingTelNum}"></DataGridTextColumn>
<DataGridTextColumn Header="地址"Width="200" Binding="{BindingAddress}"></DataGridTextColumn>
<DataGridTextColumn Header="等級"Width="50" Binding="{BindingCustLevel}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
</Grid>
</Window>
DockPanel控制元件: 可以讓容器中的控制元件貼著它的邊排列
ToolBar控制元件: 工具條控制元件
DataGrid控制元件: 可以方便的顯示錶中的內容.
注意: 需要讓IsReadOnly="True", 這樣就禁止直接在介面中更改內容
AutoGenerateColumn="False", 不使用控制元件自動生成的列, 很多情況下不符號要求
using System;
usingSystem.Collections.Generic;
using System.Linq;
using System.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Data;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Imaging;
usingSystem.Windows.Shapes;
using 三層架構基礎.Model;
namespace三層架構基礎
{
/// <summary>
/// CustomerListUI.xaml 的互動邏輯
/// </summary>
public partial class CustomerListUI :Window
{
public CustomerListUI()
{
InitializeComponent();
}
private void btnAdd_Click(objectsender, RoutedEventArgs e)
{
CustomerEditUI editUI = newCustomerEditUI();
editUI.IsInsert = true;
if(editUI.ShowDialog() == true) //ShowDialog()會阻塞呼叫程序, 進入當前視窗程序, 並且置DialogResult為false
{
LoadData();
}
}
private void btnDelete_Click(objectsender, RoutedEventArgs e)
{
Customer customer =(Customer)grid.SelectedItem;
if (customer == null)
{
MessageBox.Show("請選中行");
return;
}
if(MessageBox.Show("確認要刪除此行資料嗎?", "提示",
MessageBoxButton.YesNo)==MessageBoxResult.Yes)
{
newCustomerDAL().DeleteById(customer.Id);
LoadData();
}
}
private void btnEdit_Click(objectsender, RoutedEventArgs e)
{
CustomerEditUI editUI = newCustomerEditUI();
Customer customer =(Customer)grid.SelectedItem;
if (customer == null)
{
MessageBox.Show("請選中一行資料");
return;
}
editUI.IsInsert = false;
editUI.EditId =customer.Id; //雖然可以直接傳選中的當前customer, 但是視窗間的傳值最好使用簡單型別的資料
if (editUI.ShowDialog()==true)
{
LoadData();
}
}
private void Window_Loaded_1(objectsender, RoutedEventArgs e)
{
LoadData();
}
//用來在執行sql操作後重新整理介面的方法
private void LoadData()
{
CustomerDAL dal = newCustomerDAL();
grid.ItemsSource = dal.GetAll();
}
}
}
ShowDialog() 會阻塞當前視窗程序, 並開啟呼叫方法的視窗, 然後會預設一個為false的DialogResult值, 一旦給該屬性賦值, 就會關閉呼叫方法的視窗, 並返回DialogResult的值
封裝LoadData()方法, 用於重新整理視窗中的資料.
點選新增 修改開啟一個新的視窗CustomerEditUI
<Window x:Class="三層架構基礎.CustomerEditUI"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CustomerEditUI"Height="381" Width="639" Loaded="Window_Loaded_1"
x:Name="editWindow">
<GridContextMenuClosing="Grid_ContextMenuClosing_1">
<TextBlockHorizontalAlignment="Left" Margin="75,55,0,0"TextWrapping="Wrap" Text="姓名"VerticalAlignment="Top"/>
<TextBlockHorizontalAlignment="Left" Margin="355,55,0,0"TextWrapping="Wrap" Text="電話"VerticalAlignment="Top"/>
<TextBlockHorizontalAlignment="Left" Margin="75,120,0,0"TextWrapping="Wrap" Text="生日"VerticalAlignment="Top"/>
<TextBlockHorizontalAlignment="Left" Margin="355,120,0,0"TextWrapping="Wrap" Text="級別"VerticalAlignment="Top"/>
<TextBlockHorizontalAlignment="Left" Margin="75,210,0,0"TextWrapping="Wrap" Text="地址"VerticalAlignment="Top"/>
<TextBox x:Name="txtName"HorizontalAlignment="Left" Height="23"Margin="170,55,0,0" TextWrapping="Wrap" Text="{BindingPath=Name}" VerticalAlignment="Top" Width="120"/>
<TextBoxx:Name="txtTelNum" HorizontalAlignment="Left"Height="23" Margin="445,52,0,0"TextWrapping="Wrap" Text="{Binding Path=TelNum}" VerticalAlignment="Top"Width="120"/>
<DatePickerx:Name="Birthday" SelectedDate="{Binding Birthday}"HorizontalAlignment="Left" Margin="170,116,0,0"VerticalAlignment="Top"/>
<TextBoxx:Name="txtCustLevel" HorizontalAlignment="Left"Height="23" Margin="445,120,0,0"TextWrapping="Wrap" Text="{Binding Path=CustLevel}" VerticalAlignment="Top"Width="120"/>
<TextBoxx:Name="txtAddress" HorizontalAlignment="Left"Height="23" Margin="170,210,0,0"TextWrapping="Wrap" Text="{Binding Path=Address}" VerticalAlignment="Top"Width="395"/>
<Buttonx:Name="btnSave" Content="儲存"HorizontalAlignment="Left" Margin="355,278,0,0"VerticalAlignment="Top" Width="75"Click="btnSave_Click"/>
<Buttonx:Name="btnCancel" Content="取消"HorizontalAlignment="Left" Margin="490,278,0,0"VerticalAlignment="Top" Width="75"Click="btnCancel_Click"/>
</Grid>
</Window>
將TextBox的Text屬性動態繫結到外部物件, 在後臺中給editWindow.DataContext賦值(需要根據情況, 因為新增和修改開啟的是同一個視窗)
在CustomerEditUI視窗中定義兩個屬性:
//通過視窗的屬性傳值
//是否插入
//如果不是插入就賦值要編輯的Id
public bool IsInsert { get; set; }
public long EditId { get; set; }
用於判斷是要進行哪種操作
using System;
usingSystem.Collections.Generic;
using System.Linq;
using System.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Data;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Imaging;
usingSystem.Windows.Shapes;
using 三層架構基礎.Model;
namespace三層架構基礎
{
/// <summary>
/// CustomerEditUI.xaml 的互動邏輯
/// </summary>
public partial class CustomerEditUI :Window
{
//通過視窗的屬性傳值
//是否插入
//如果不是插入就賦值要編輯的Id
public bool IsInsert { get; set; }
public long EditId { get; set; }
public CustomerEditUI()
{
InitializeComponent();
}
private void btnSave_Click(objectsender, RoutedEventArgs e)
{
if (IsInsert)
{
//插入資料
Customer customer =(Customer)editWindow.DataContext;
newCustomerDAL().Insert(customer);
}
else
{
//修改資料使用Update
//再次取資料庫的資料, 保證資料正確性
Customer customer =(Customer)editWindow.DataContext;
newCustomerDAL().Update(customer);
}
DialogResult = true;
}
private voidGrid_ContextMenuClosing_1(object sender, ContextMenuEventArgs e)
{
DialogResult = false;
this.Close();
}
private void btnCancel_Click(objectsender, RoutedEventArgs e)
{
}
private void Window_Loaded_1(objectsender, RoutedEventArgs e)
{
if (IsInsert == true)
{
Customer customer = newCustomer();
//有時候會要求一些預設值
customer.CustLevel ="2";
editWindow.DataContext =customer;
}
else//編輯修改
{
//原則上: 視窗傳值, 容器中儲存值儘量放簡單資料型別
//再次使用EditId讀取資料, 保證資料是最新的
Customer customer = newCustomerDAL().GetById(EditId);
//填充頁面當前的customer, 使用資料繫結比較方便
editWindow.DataContext =customer;
}
}
}
}
---------------------- ASP.Net+Unity開發、.Net培訓、期待與您交流! ----------------------詳細請檢視:www.itheima.com相關推薦
黑馬程式設計師 C#學習筆記⑥ 三層架構基礎實現員工資訊管理
---------------------- ASP.Net+Unity開發、.Net培訓、期待與您交流! ---------------------- 三層架構定義 1、表現層(UIL):通俗講就是展現給使用者的介面,即使用者在使用一個系統的時候他的所見所得。 2、業
【C#】簡單三層架構(MVC)實現學生資訊管理
一個簡單的demo,程式碼不多,適合初學者。 三層架構分別是:表示層(UI)、業務邏輯層(NLL)、資料訪問層(DAL). 視訊講解教程: 微課7-1三層架構的搭建-----https://2d.hep.com.cn/47486/98 微課7-2顯示學生資訊--------htt
黑馬程式設計師 C#學習筆記⑤ 省市縣三級聯動查詢
---------------------- ASP.Net+Unity開發、.Net培訓、期待與您交流! ----------------------詳細請檢視:www.itheima.com 實現一個可以動態的進行省市縣查詢的程式 一 基本原理: 通過ADO.NET技
黑馬程式設計師—C語言筆記—陣列和字串
一、陣列 1、概念:是用來儲存一組資料的; a、構造型別:有無數個基本資料型別組成的型別; b、特點:(1)、只能存放一種型別的資料;(2)、裡面存放的資料稱為“元素”; 2、陣列的定義 a、定義格式: 資料型別 陣列名[元素個數]; b、簡單使用: (1)、簡單的初始化;int age[3] = {11,
黑馬程式設計師-OC學習筆記-----記憶體管理
移動裝置的記憶體極其有限,每個app所能佔用的記憶體是有限制的.當app所佔用的記憶體較多時,系統會發出記憶體警告,這時得回收一些不需要再使用的記憶體空間。比如回收一些不需要使用的物件、變數等。基本的資料型別是放在記憶體的棧裡面,這是不需要我們去管理的,系統會自動回收。但是
黑馬程式設計師_學習筆記JAVA基礎總結
1、方法過載 方法覆蓋 過載:一個類中一種功能的多種實現方式,呼叫哪種實現方式,根據呼叫者給出的引數。有兩個或多個方法方法名相同,但是引數型別或者引數個數或者引數順序不同。覆蓋:子類重寫父類的一個函式,函式名,引數,返回型別都相同。 覆蓋的應用: 當子類需要父
黑馬程式設計師--JQuery學習筆記
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS開發</a>、<a href="http://edu.csdn.net
黑馬程式設計師_Java學習筆記之7K面試題交通等管理系統
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">
黑馬程式設計師-IOS學習筆記(二)常用關鍵字和方法
------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流!------- 常用關鍵字和方法: 一.記憶體管理情況 1- autorelease,當用戶的程式碼在持續執行時,自動釋放池是不會被銷燬的,這段時間內使用者可以安全地使用自動釋放的物件。當
黑馬程式設計師—C語言筆記—記憶體剖析
一、進位制 1、定義:是一種計數的方式,數值的表示形式。 2、常用的4種進位制: 二進位制以0b/0B開頭如int num1 = 0b1100; 八進位制以0開頭如int num2 = 014; 十進位制如 int num3 = 12; 十六進位制以0x/0X開頭如int num4=0xc;
黑馬程式設計師 反射學習筆記
----------android培訓、java培訓、java學習型技術部落格、期待與您交流!---------- 反射: “反射就是把Java類中的各種成分對映成相應的java類”,而在此之前,首先是必須獲得類的Class物件,再呼叫Class的相關方法,獲取例項類中
黑馬程式設計師-OC學習筆記-點方法、成員變數作用域以及set方法和get方法@property的綜合題
------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! ------- 1. OC建立物件的拓展: Frac
黑馬程式設計師——C語言筆記之資料型別與常量
------- android培訓、java培訓、iOS培訓、.Net培訓、期待與您交流! ---------- 1、什麼是資料型別 資料型別是指資料以何種方式儲存在記憶體中,不同的型別儲存方
黑馬程式設計師--C語言自學筆記---02基礎語法
1. 關鍵字 2. 識別符號 :由字母、數字、下劃線和美元符號組成,不能以字母開頭。 識別符號命名規範: 1) 名稱要有意義,不要隨便命名成aaaa,bbbb等,要命名成userName,uName等; 2) 採用駝峰命名法:即形如
黑馬程式設計師-C語言基礎學習(一)
C語言學習筆記一 ---既然決定14年要好好的努力一次,那麼就不要再輕言放棄,不再在隨波逐流。只有努力過、拼搏過,才會知道自己行還是不行!為自己加油!--- ---總結的知識點可能有不正確的地方,如果有發現請留言給我,我一定及時更正,不讓錯誤的知識去誤導大家,有好的意見
C++學習筆記 (三) ---- string 類
引言:在 C++ 中,大大加強了對字串的支援和處理,除了相容 C 語言的字串,還內建了完全可以替換 C語言中的字元陣列和字串指標的 string 類。 使用 string 類需要包含標頭檔案 <string>。 簡單例子: #
C#學習筆記 三
正文共: 2947字 預計閱讀時間: 8分鐘 寫在前面的話 : 程式語言的出現是為了讓機器更好的服務人類, 所以越是高階的程式語言人類使用起來就越方便, 隨著計算機硬體的發展高階程式設計終將會被大多數程式設計人員接受並使用。 但是學習C、彙編等與底層語言會使得程式設計人員更
c#學習筆記三 如何訪問另一個頁面的控制元件資料
在Vs2005中新建一個Web專案,新增兩個Web窗體(Default、Default2),在Default窗體上新增兩個標準控制元件,一個TextBox(TextBox1)、一個Button(Button1),設定Button1的PostBackUrl屬性指向D
黑馬程式設計師_Java學習日記2_面向物件總結1
----------------------android培訓、java培訓、期待與您交流! --------------------- 1.關於main函式的講解 主函式,是一個特殊的函式,作為程式的入口,可以被jvm呼叫。 主函式的定義: public:代表該函式的許
黑馬程式設計師_Java學習日記25_高新技術4
----------------------android培訓、java培訓、期待與您交流! --------------------- 泛型 1.入門泛型的基本應用 JDK1.5的集合類希望你在定義集合時,明確表示你要向集合中儲存哪種型別的資料,無法加入指定型別以外的