前面我们介绍了三层结构,下来我们就看看他在应用程序中是怎么做的:

在这之前我们应该在数据库中建好数据库,并添加好表格

在做这些项目的时候,我们先要把引用什么的都添加好,直接添加项目引用就好。

实体类:里面可以添加多张表的实体类,我们在这里做的是两张表的

先做一个实体类,方便使用,只需要做一个实体类对象,就可以用它里面的属性并赋值了

//方便序列化时应用
[Serializable]
//要将实体类公开上,方便后面使用
public class Depart
{
int departId;
public int DepartId
{
get { return departId; }
set { departId = value; }
}
string departName;
public string DepartName
{
get { return departName; }
set { departName = value; }
}
}

[Serializable]
public class ClassInfo
{
int classId;
public int ClassId
{
get { return classId; }
set { classId = value; }
}
string className;
public string ClassName
{
get { return className; }
set { className = value; }
}
int departId;
public int DepartId
{
get { return departId; }
set { departId = value; }
}
}

SQLServerDAL(数据访问层):

(1)通用数据库访问类

namespace SQLServerDAL
{
//通用数据库访问类,不加访问修饰符表示只能被当前工程所用
class DBHelper
{
//连接字符串
string connString = "server=.\\sqlexpress;database=SchoolDB2;uid=sa;pwd=199298";
//连接数据库,这个方法可以用来执行增删改命令
public int ExecuteNonQuary(string sql,SqlParameter []ps)
{
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = sql;
cmd.Parameters.AddRange(ps);
conn.Open();
int x = cmd.ExecuteNonQuery();
conn.Close();
return x;
}
//连接数据库,用来执行查询命令
public DataTable GetData(string sql,SqlParameter[]ps)
{
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = sql;
cmd.Parameters.AddRange(ps);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
}

(2)特定数据库访问类:

Departs表的访问:

public class DepartService
{
//通用数据库访问类的对象,类里面的方法都可以访问
DBHelper db = new DBHelper();
//往数据库中添加记录
public void AddDepart(Depart depart)
{
string sql = "Insert Into Depart(departName)Values(@departName)";
SqlParameter[] ps = new SqlParameter[] {
new SqlParameter("@DepartName",depart.DepartName)
};
//调用通用数据库访问类中的增删改方法执行添加
db.ExecuteNonQuary(sql,ps);
}
//更改数据库中的记录
public void UpdateDepart(Depart depart)
{
string sql = "Update Depart set departName=@departName where departId=@departId";
SqlParameter[] ps = new SqlParameter[] {
new SqlParameter("@DepartName",depart.DepartName),
new SqlParameter("@DepartId",depart.DepartId)
};
db.ExecuteNonQuary(sql, ps);
}
//根据id删除数据库中的记录
public void DeleteDepartById(int departId)
{
string sql = "Delete  from Depart where departId=@departId";
SqlParameter[] ps = new SqlParameter[] {
new SqlParameter("@departId",departId)
};
db.ExecuteNonQuary(sql, ps);
}
//根据id查询数据库中的记录
public Depart SelectDepartById(int departId)
{
string sql = "Select * from Depart where departId=@departId";
SqlParameter[] ps = new SqlParameter[] {
new SqlParameter("@departId",departId)
};
DataTable dt=db.GetData(sql,ps);
//判断是否有这个id的记录
if (dt.Rows.Count==0)
{
return null;
}
//将取到的这一行数据给数据行
DataRow dr=dt.Rows[0];
//座椅个实体类对象并赋值
Depart depart = new Depart();
depart.DepartId = (int)dr["departId"];
depart.DepartName =(string) dr["departName"];
//返回实体对象
return depart;
}
//查询数据库中的所有记录
public List<Depart> SelectDepart()
{
string sql = "Select * from Depart";
SqlParameter[] ps = new SqlParameter[] {};
DataTable dt = db.GetData(sql, ps);
List<Depart> list = new List<Depart>();
foreach (DataRow dr in dt.Rows)
{
Depart depart = new Depart();
depart.DepartId=(int)dr["departId"];
depart.DepartName = (string)dr["departName"];
list.Add(depart);
}
return list;
}
}

Classes表的访问:

public class ClassInfoService
{
DBHelper db = new DBHelper();
public void AddClassInfo(ClassInfo classInfo)
{
string sql = "Insert Into Classes(className, departId)Values(@className, @departId)";
SqlParameter[] ps = new SqlParameter[] {
new SqlParameter("@ClassName",classInfo.ClassName),
new SqlParameter("@DepartId",classInfo.DepartId),
};
db.ExecuteNonQuary(sql, ps);
}
public void UpdateClassInfo(ClassInfo classInfo)
{
string sql = "Update  Classes set className=@className,departId=@ departId where classId=@classId";
SqlParameter[] ps = new SqlParameter[] {
new SqlParameter("@ClassName",classInfo.ClassName),
new SqlParameter("@DepartId",classInfo.DepartId)
};
db.ExecuteNonQuary(sql, ps);
}
public void DeleteClassInfoById(int classId)
{
string sql = "Delete  from Classes where classId=@classId";
SqlParameter[] ps = new SqlParameter[] {
new SqlParameter("@classId",classId)
};
db.ExecuteNonQuary(sql, ps);
}
public ClassInfo SelectClassInfoById(int classId)
{
string sql = "Select * from Classes where classId=@classId";
SqlParameter[] ps = new SqlParameter[] {
new SqlParameter("@classId",classId)
};
DataTable dt = db.GetData(sql, ps);
if (dt.Rows.Count == 0)
{
return null;
}
DataRow dr = dt.Rows[0];
ClassInfo classInfo = new ClassInfo();
classInfo.ClassId = (int)dr["classId"];
classInfo.ClassName = (string)dr["className"];
classInfo.DepartId = (int)dr["departId"];
return classInfo;
}
public List<ClassInfo> SelectClassInfo()
{
string sql = "Select * from Classes";
SqlParameter[] ps = new SqlParameter[] { };
DataTable dt = db.GetData(sql, ps);
List<ClassInfo> list = new List<ClassInfo>();
foreach (DataRow dr in dt.Rows)
{
ClassInfo classInfo = new ClassInfo();
classInfo.ClassId = (int)dr["classId"];
classInfo.ClassName = (string)dr["className"];
classInfo.DepartId = (int)dr["departId"];
list.Add(classInfo);
}
return list;
}
public List<ClassInfo> SelectClassInfoByDepartId(int departId)
{
string sql = "Select * from Classes where departId=@departId";
SqlParameter[] ps = new SqlParameter[] {
new SqlParameter("@departId",departId)
};
DataTable dt = db.GetData(sql, ps);
List<ClassInfo> list = new List<ClassInfo>();
foreach (DataRow dr in dt.Rows)
{
ClassInfo classInfo = new ClassInfo();
classInfo.ClassId = (int)dr["classId"];
classInfo.ClassName = (string)dr["className"];
classInfo.DepartId = (int)dr["departId"];
list.Add(classInfo);
}
return list;
}
}

BLL(业务逻辑层):

在这里面我们现在只做调用,随着学习,我们会逐渐完善里面的内容,不仅仅只做调用。

Departs表的业务逻辑层:

public class DepartManager
{
//做一个静态的DepartService对象
static DepartService ds = new DepartService();
//逐个调用数据访问层里面特定的数据库访问类里面的方法
public static void AddDepart(Depart depart)
{
ds.AddDepart(depart);
}
public static void UpdateDepart(Depart depart)
{
ds.UpdateDepart(depart);
}
public static void DeleteDepartById(int departId)
{
ds.DeleteDepartById(departId);
}
public static Depart SelectDepartById(int departId)
{
return ds.SelectDepartById(departId);
}
public static List<Depart> SelectDepart()
{
return ds.SelectDepart();
}
}

Classes表的业务逻辑层:

public class ClassInfoManager
{
static ClassInfoService cs = new ClassInfoService();
public static void AddClassInfo(ClassInfo classInfo)
{
cs.AddClassInfo(classInfo);
}
public static void UpdateClassInfo(ClassInfo classInfo)
{
cs.UpdateClassInfo(classInfo);
}
public static void DeleteClassInfoById(int classId)
{
cs.DeleteClassInfoById(classId);
}
public static ClassInfo SelectClassInfoById(int classId)
{
return cs.SelectClassInfoById(classId);
}
public static List<ClassInfo> SelectClassInfo()
{
return cs.SelectClassInfo();
}
public static List<ClassInfo> SelectClassInfoByDepartId(int departId)
{
return cs.SelectClassInfoByDepartId(departId);
}
}

最后是数据表示层:

在这里面我们要将数据库中表里面的信息通过窗体加载事件显示到窗体上,再通过窗体上的各个按钮实现增删改。

主窗体中的窗体设计:

125240108.png

看主窗体中的程序是怎么写的:

public frmMain()
{
InitializeComponent();
}
//学院管理按钮
private void button1_Click(object sender, EventArgs e)
{
//做一个frmDepart对象
frmDepart fd = new frmDepart();
//将他显示出来
fd.ShowDialog();
}
private void button2_Click(object sender, EventArgs e)
{
//做一个frmClasses对象
frmClasses fc = new frmClasses();
//将他显示出来
fc.ShowDialog();
}

再来看frmDepart窗体的设计:

125649861.png

下面来看看窗体上的按钮的功能:

public partial class frmDepart : Form
{
public frmDepart()
{
InitializeComponent();
}
private void frmDepart_Load(object sender, EventArgs e)
{
//填充控件
FillListView();
}
private void FillListView()
{
//清空控件
this.listDepart.Items.Clear();
//调用业务方法将数据显示到列表控件中
List<Depart> departs = DepartManager.SelectDepart();
//将每一条数据都做成一个列表项,添加到列表中去
foreach (Depart depart in departs)
{
ListViewItem lvi = new ListViewItem();
lvi.Text = depart.DepartId.ToString();
lvi.SubItems.Add(depart.DepartName);
//将列表中的Tag属性设置为某个学院对象
lvi.Tag = depart;
this.listDepart.Items.Add(lvi);
}
}
//设置编辑状态变量为新增
bool eidtFalg= false;
/// <summary>
/// 添加按钮,用来清空输入框中的内容,并将编辑状态设置为新增
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAdd_Click(object sender, EventArgs e)
{
//添加按钮
//将输入框中的内容清空
//设定编辑状态为新增
//初始化
InitInputControl();
//设定编辑状态为新增
eidtFalg = false;
}
//初始化方法
private void InitInputControl()
{
//将输入框中的内容都初始化
this.txtDepartId.Text = "";
this.txtDepartName.Text = "";
}
//设置全局变量
int departId = 0;
private void bnSave_Click(object sender, EventArgs e)
{
//保存按钮
//首先判断编辑状态是否为新增还是编辑
//根据编辑状态决定调用哪个方法
//保存完成后,将编辑状态设置为新增
//清空输入框
//先从界面中取值
int departId = int.Parse(this.txtDepartId.Text);
string departName = this.txtDepartName.Text;
//将取到的值作成一个实体对象
Depart depart = new Depart();
depart.DepartId = departId;
depart.DepartName = departName;
//判断编辑状态
if (!eidtFalg)
{
//为新增,调用添加对象的方法
BLL.DepartManager.AddDepart(depart);
}
else
{
//为编辑,调用修改对象的方法
BLL.DepartManager.UpdateDepart(depart);
}
//将输入框中清空
InitInputControl();
//设置编辑状态为新增
eidtFalg = false ;
//填充列表控件
FillListView();
}
/// <summary>
/// 删除按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnDelete_Click(object sender, EventArgs e)
{
//首先查看ListView中是否有一行被选中
//获取这一行中主键的值
//将值传递给删除方法
//查看ListView中是否有一行被选中
if (this.listDepart.SelectedItems.Count==0)
{
return;
}
//有一行被选中,显示一个提示框,问用户是否真的要删除所选的记录
DialogResult dr= MessageBox.Show("是否真的要删除?","提示框",MessageBoxButtons.YesNo,MessageBoxIcon.Question,MessageBoxDefaultButton.Button2);
//用户选择的是No的时候,返回
if (dr==DialogResult.No)
{
return;
}
//选择的是Yes的时候,将选中的这行记录做成一个对象,
object obj=this.listDepart.SelectedItems[0].Tag;
Depart depart = obj as Depart;
//调用SelectClassInfoByDepartId方法,查询所选择的这行记录的主键是否在Classes表中被引用
List<ClassInfo> classInfos = BLL.ClassInfoManager.SelectClassInfoByDepartId(depart.DepartId);
//如果查询的结果的条数不为0,则不能删除
if (classInfos.Count!=0)
{
MessageBox.Show("这条记录在后面有引用,不能删","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
return;
}
//如果查询的结果的条数为0,则调用删除掉的方法,根据主键将这行记录删除掉
BLL.DepartManager.DeleteDepartById(depart.DepartId);
//填充ListView控件
FillListView();
}
private void listDepart_DoubleClick(object sender, EventArgs e)
{
//首先查看ListView中是否有一行被选中
//将编辑状态设置为编辑
//将选中的行中的数据显示在输入框中
if (this.listDepart.SelectedItems.Count == 0)
{
return;
}
//将编辑状态设置为编辑
eidtFalg = true;
//将选中的这行记录做成一个对象
object obj = this.listDepart.SelectedItems[0].Tag;
Depart depart = obj as Depart;
//将选中的这条记录的值显示到输入框中
this.txtDepartId.Text = depart.DepartId.ToString();
this.txtDepartName.Text = depart.DepartName;
//这个全局变量的值等于对象的主键
departId = depart.DepartId;
}
//退出按钮,关闭控件
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
}

看执行后的结果:

131357733.png

下一里面的套路都一样,这样我们掌握好了这个的各种功能的写法,下一个就能轻松地写出来,加油!!!

后续还会有关于三层结构的升级做法,我们会将这个过程做的越来越清晰明了,让以后的维护工作尽可能的简单方便。