您的位置:首页 > 职场人生

黑马程序员 C#学习笔记⑥ 三层架构基础实现员工信息管理

2014-03-21 20:23 1001 查看
----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
三层架构定义

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 Id=@Id",

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 whereId=@Id",

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]=@Name

,[Birthday]=@Birthday

,[Address]=@Address

,[TelNum]=@TelNum

,[CustLevel]=@CustLevel

WhereId=@Id",

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐