步骤01
2.操作步骤
在开始之前,要确保 Visual Studio 和 SQL Server Management Studio 已经安装成功,并且SQL服务已经打开了。
2.1 建库、建表
将下图中的名字复制下来。后面的步骤中会用到。(DESKTOP-ADKCETM)
Y_strong
根据题目要求建立表结构。(注意这里并没有按照题目要求的设置性别字段的数据类型为Char(4),而是设置为了Char(2),因为一个中文占2位)
然后将Oid设置为主键,并将其设置为自动增加。
(注意下图中的Char(4)为未修改之前,应该为Char(2),不要被下图混淆了,我给上错了图。。。)
2.2 添加测试数据
设置好表的结构后,就点击下图中的刷新按钮,然后再去选择编辑前200行。
随便添加几条测试数据。
这里先统一一下规则,就是姓名只能2-4个中文,性别只能男或者女,电话是11位数字,后面的三个字段都是1-3位数字。会在B层进行逻辑判断的时候,主要对描述的这些规则进行验证。
2.3 在VS中创建项目
选择ASP.NET Web应用程序 (YYYDemo P_ULayer)
点击确定
现在是这个样子
在解决方案上右键—添加—新建项目。
选择类库项目。 (P_BLayer)
同样的步骤,再新建一个类库项目。(P_DLayer)
现在的解决方案是下图所示的情况。
2.4 添加引用
在P_ULayer项目中添加对P_BLayer项目的引用,在P_BLayer项目中添加对P_DLayer项目的引用。
U中添加对B的引用:
B中添加对D的引用:
现在是这个样子:
修改程序集名称和默认命名空间名称
同样的方法,修改B层和D层项目的这两个属性,都是修改为 YYYDemo.XXX
2.5 添加类和页面
①:B中添加类:
BLayer
②:同样的方法,在D中添加一个类(DLayer)
③:在U层项目中,添加一个.aspx web窗体和一个.master母版页
③-1:添加web窗体
ShowAll
③-2:添加母版页
Site
完成上述操作,现在的结构应该是这样的:
2.6 建立VS与SSMS的连接
现在将 “2.1 建库、建表” 步骤中的名字拿过来
可以看到,连接已经建立。
把下图的连接字符串复制下来
Data Source=DESKTOP-ADKCETM;Initial Catalog=Y_strong;Integrated Security=True
2.7 实现显示功能
①:修改D_Layer.cs的代码,把 “2.6 步骤” 中的连接字符串拿过来。
红框为新增或修改的代码,后续的步骤中也是同样的意思。
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace YYYDemo.P_DLayer
{
public class DLayer
{
//创建数据库连接
private SqlConnection CreateConnection()
{
return new SqlConnection(
"Data Source=DESKTOP-ADKCETM;Initial Catalog=Y_strong;Integrated Security=True"
);
}
//关闭连接
public void D_CloseConn()
{
CreateConnection().Close();
}
//获取全部的账户信息,以DataSet数据类型返回
public DataSet GetAllAccount_TO_DataSet()
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
"SELECT * FROM owner", conn
);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
}
}
②:修改B_Layer的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YYYDemo.P_DLayer;
using System.Data;
using System.Text.RegularExpressions;//正则表达式
using System.Runtime.InteropServices;//为了实现一个弹窗
namespace YYYDemo.P_BLayer
{
public class BLayer
{
//提示框,这两行照着写上即可,不必理解原理,会使用就行
[DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr handle, String message, String title, int type);
public DataSet GetAllAccount_TO_DataSet()
{
return new DLayer().GetAllAccount_TO_DataSet();
}
public void B_CloseConn()
{
new DLayer().D_CloseConn();
}
}
}
③-1:修改U层ShowAll页面
然后到设计界面去修改GridView。
这个数据字段很关键,是跟数据表中的字段一一对应的,所以需要跟数据表中的字段的名称一样。
页眉文本就是显示在界面上的文本。
同样的方法,添加如下几列:
对应的GridView的代码如下:
(那个SortExpression属性可以删掉,因为我们并不使用它实现任何功能。)
截止到现在ShowAll.aspx的代码
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ShowAll.aspx.cs" Inherits="P_ULayer.ShowAll" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>小区业主列表</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="Div_lbl_Topic">
<asp:Label runat="server" ID="lbl_Topic" Text="小 区 业 主 列 表"></asp:Label>
</div>
<asp:GridView ID="gView" runat="server"
AllowPaging="True"
AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Name" HeaderText="姓名" SortExpression="Name" />
<asp:BoundField DataField="Sex" HeaderText="性别" />
<asp:BoundField DataField="Phone" HeaderText="联系电话" SortExpression="Phone" />
<asp:BoundField DataField="BuildNum" HeaderText="楼号" SortExpression="BuildNum" />
<asp:BoundField DataField="Unit" HeaderText="单元" SortExpression="Unit" />
<asp:BoundField DataField="RoomNum" HeaderText="房间号" SortExpression="RoomNum" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
编写ShowAll.aspx.cs的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using YYYDemo.P_BLayer;
namespace P_ULayer
{
public partial class ShowAll : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.gView.DataSource = new BLayer().GetAllAccount_TO_DataSet();
this.gView.DataBind();
new BLayer().B_CloseConn();
}
}
}
运行测试:( 一定要让VS当前活动窗口为ShowAll.aspx或者是****ShowAll.aspx.cs才可以摁下F5运行)
可以看到已经能够正常显示出数据表的信息了。
2.8 新建内容页,并编辑母版页和内容页以及ShowAll页的UI
①:编写Site.Master
隐藏起来的table内容可以直接查看下面的代码。
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="P_ULayer.Site" %>
<!DOCTYPE html>
<html>
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="Div_hLink_TO_01">
<asp:HyperLink ID="hLink_TO_ShowAll" runat="server" NavigateUrl="~/ShowAll.aspx" Target="_self" Text="返回主页"></asp:HyperLink>
</div>
<asp:ContentPlaceHolder ID="ContentPlaceHolder_DivLabel" runat="server">
</asp:ContentPlaceHolder>
<br />
<br />
<table id="tableUI">
<tr>
<td style="width: 48%" class="td_Left">
<asp:Label ID="lbl_Name" runat="server" Text="姓名:"></asp:Label>
</td>
<td style="width: 50%">
<asp:TextBox ID="textBox_Name" runat="server" Font-Size="16pt"></asp:TextBox>
</td>
</tr>
<tr>
<td class="td_Left">
<asp:Label ID="lbl_Sex" runat="server" Text="性别:"></asp:Label>
</td>
<td>
<asp:RadioButton ID="radioBtn_Boy" runat="server" GroupName="Sex" Text="男" Checked="True" />
<asp:RadioButton ID="radioBtn_Girl" runat="server" GroupName="Sex" Text="女" />
</td>
</tr>
<tr>
<td class="td_Left">
<asp:Label ID="lbl_Phone" runat="server" Text="联系电话:"></asp:Label>
</td>
<td>
<asp:TextBox ID="textBox_Phone" runat="server" Font-Size="16pt"></asp:TextBox>
</td>
</tr>
<tr>
<td class="td_Left">
<asp:Label ID="lbl_BuildNum" runat="server" Text="楼号:"></asp:Label>
</td>
<td>
<asp:TextBox ID="textBox_BuildNum" runat="server" Font-Size="16pt"></asp:TextBox>
</td>
</tr>
<tr>
<td class="td_Left">
<asp:Label ID="lbl_Unit" runat="server" Text="单元:"></asp:Label>
</td>
<td>
<asp:TextBox ID="textBox_Unit" runat="server" Font-Size="16pt"></asp:TextBox>
</td>
</tr>
<tr>
<td class="td_Left">
<asp:Label ID="lbl_RoomNum" runat="server" Text="房间号:"></asp:Label>
</td>
<td>
<asp:TextBox ID="textBox_RoomNum" runat="server" Font-Size="16pt"></asp:TextBox>
</td>
</tr>
</table>
<br />
<br />
<asp:ContentPlaceHolder ID="ContentPlaceHolder_DivButton" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
②:添加内容页:
可以看到新建的内容页为下图所示:
同样的方法,再新建一个内容页,然后修改两个内容页的名字,具体效果如下:
③:编辑内容页的代码
③-1:编辑后的AddAccount内容页:
在设计界面,双击Button,为其添加一个点击事件。
下图这个函数是双击后自动创建的
回到AddAccount这个内容页的.aspx中,可以看到:
自动多了一个这个属性。
截止到目前,AddAccount.aspx内容页的代码如下:
<%@ Page Title="新增业主" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="AddAccount.aspx.cs" Inherits="YYYDemo.P_ULayer.WebForm1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder_DivLabel" runat="server">
<div id="Div_lbl_Topic">
<asp:Label ID="lbl_Topic" runat="server" Text="新 增 业 主"></asp:Label>
</div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder_DivButton" runat="server">
<div id="Div_btnSubmit">
<asp:Button ID="btnSubmit" runat="server" class="CSS_class_btnSubmit" Text="提交" OnClick="btnSubmit_Click"/>
</div>
</asp:Content>
③-2:跟③-1同样的 步骤,去修改AlterAccount内容页的代码。
截止到目前,AlterAccount.aspx的代码:
<%@ Page Title="修改业主" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="AlterAccount.aspx.cs" Inherits="YYYDemo.P_ULayer.WebForm2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder_DivLabel" runat="server">
<div id="Div_lbl_Topic">
<asp:Label ID="lbl_Topic" runat="server" Text="修 改 业 主"></asp:Label>
</div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder_DivButton" runat="server">
<div id="Div_btnSubmit">
<asp:Button ID="btnSubmit" runat="server" Text="提交" class="CSS_class_btnSubmit" OnClick="btnSubmit_Click" />
</div>
</asp:Content>
④:为ShowAll页面新加一个链接控件
截止到目前,ShowAll页面的代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ShowAll.aspx.cs" Inherits="P_ULayer.ShowAll" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>小区业主列表</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="Div_lbl_Topic">
<asp:Label runat="server" ID="lbl_Topic" Text="小 区 业 主 列 表"></asp:Label>
</div>
<div>
<br /><br />
<asp:HyperLink Target="_self" NavigateUrl="~/AddAccount.aspx" runat="server" ID="hLink_AddAccount" Text="新增业主"></asp:HyperLink>
<br /><br /><br /><br />
</div>
<asp:GridView ID="gView" runat="server"
AllowPaging="True"
AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Name" HeaderText="姓名" SortExpression="Name" />
<asp:BoundField DataField="Sex" HeaderText="性别" />
<asp:BoundField DataField="Phone" HeaderText="联系电话" SortExpression="Phone" />
<asp:BoundField DataField="BuildNum" HeaderText="楼号" SortExpression="BuildNum" />
<asp:BoundField DataField="Unit" HeaderText="单元" SortExpression="Unit" />
<asp:BoundField DataField="RoomNum" HeaderText="房间号" SortExpression="RoomNum" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
运行测试:
可以正常的进入到新增业主界面和返回主页。
2.9 实现新增业主功能
先修改DLayer的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace YYYDemo.P_DLayer
{
public class DLayer
{
//创建数据库连接
private SqlConnection CreateConnection()
{
return new SqlConnection(
"Data Source=DESKTOP-ADKCETM;Initial Catalog=Y_strong;Integrated Security=True"
);
}
//关闭连接
public void D_CloseConn()
{
CreateConnection().Close();
}
//获取全部的账户信息,以DataSet数据类型返回
public DataSet GetAllAccount_TO_DataSet()
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
"SELECT * FROM owner", conn
);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
//添加一个账户
public void AddAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"INSERT INTO owner(name,sex,phone,buildnum,unit,roomnum) " +
"VALUES(N'{0}','{1}',N'{2}',N'{3}',N'{4}',N'{5}')"
, name, sex, phone, buildNum, unit, roomNum),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
再修改BLayer的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YYYDemo.P_DLayer;
using System.Data;
using System.Text.RegularExpressions;//正则表达式
using System.Runtime.InteropServices;//为了实现一个弹窗
namespace YYYDemo.P_BLayer
{
public class BLayer
{
//提示框,这两行照着写上即可,不必理解原理,会使用就行
[DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr handle, String message, String title, int type);
public DataSet GetAllAccount_TO_DataSet()
{
return new DLayer().GetAllAccount_TO_DataSet();
}
public void B_CloseConn()
{
new DLayer().D_CloseConn();
}
string errorStr = "";//这个也可以设置成局部变量,只不过让RegularCheck_Add(Update)_TO_Bool函数多传递一个参数而已。
//添加账户时正则表达式对输入数据的验证
private bool RegularCheck_Add_TO_Bool(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";//2-4个中文
string rStr_Phone = @"^\d{11}$";//11位数字
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";//1-3位数字
if (!Regex.IsMatch(name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(buildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(roomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
DataTable table = GetAllAccount_TO_DataSet().Tables[0];
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < table.Rows.Count; i++)
{
if (phone == table.Rows[i][3].ToString())
equal_Phone = true;
if (
buildNum == table.Rows[i][4].ToString() &&
unit == table.Rows[i][5].ToString() &&
roomNum == table.Rows[i][6].ToString()
)
equal_Position = true;
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
B_CloseConn();
return flag;
}
//添加一个账户
public string AddAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
if (RegularCheck_Add_TO_Bool(name, sex, phone, buildNum, unit, roomNum))
{
errorStr = "新增业主信息成功!";
new DLayer().AddAnAccount(name, sex, phone, buildNum, unit, roomNum);
}
else
errorStr += "\n新增业主信息失败!";
return errorStr;
}
}
}
修改AddAccount.aspx.cs文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using YYYDemo.P_BLayer;
namespace YYYDemo.P_ULayer
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
char sex = '男';
if ((Master.FindControl("radioBtn_Girl") as RadioButton).Checked)
sex = '女';
string message = new BLayer().AddAnAccount(
(Master.FindControl("textBox_Name") as TextBox).Text.ToString(),
sex,
(Master.FindControl("textBox_Phone") as TextBox).Text.ToString(),
(Master.FindControl("textBox_BuildNum") as TextBox).Text.ToString(),
(Master.FindControl("textBox_Unit") as TextBox).Text.ToString(),
(Master.FindControl("textBox_RoomNum") as TextBox).Text.ToString()
);
BLayer.MessageBox(IntPtr.Zero, message, "提示!", 0);
}
}
}
- Master.FindControl(“IDName”)
这个代码的意思是通过id寻找在母版页上的控件 - BLayer.MessageBox(IntPtr.Zero, message, “提示!”, 0);
第二个参数(string 类型)表示的是提示框显示的文本,第三个参数(string 类型)是提示框左上角的文本,第四个参数(int 类型)是按钮的个数,0就是一个确定按钮,1就是一个确定按钮、一个取消按钮(后面在删除功能上用到)。
运行测试:
输入正确数据的时候:
输入错误数据的时候:
可以看到已经可以正常的进行验证与添加,添加成功后去SQLserver上看一下表的数据,发现已经添加上了。
2.10 实现修改业主信息功能
先修改DLayer的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace YYYDemo.P_DLayer
{
public class DLayer
{
//创建数据库连接
private SqlConnection CreateConnection()
{
return new SqlConnection(
"Data Source=DESKTOP-ADKCETM;Initial Catalog=Y_strong;Integrated Security=True"
);
}
//关闭连接
public void D_CloseConn()
{
CreateConnection().Close();
}
//获取全部的账户信息,以DataSet数据类型返回
public DataSet GetAllAccount_TO_DataSet()
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
"SELECT * FROM owner", conn
);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
//添加一个账户
public void AddAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"INSERT INTO owner(name,sex,phone,buildnum,unit,roomnum) " +
"VALUES(N'{0}','{1}',N'{2}',N'{3}',N'{4}',N'{5}')"
, name, sex, phone, buildNum, unit, roomNum),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
//通过手机号获得一个账户的信息,以DataSet数据类型返回;
//这个函数是为了在B层通过手机号获取账户的id
public DataSet GetAnAccountByPhone_TO_DataSet(string phone)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE phone=N'{0}'", phone),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
//通过id获得一个账户的信息,以DataSet数据类型返回
public DataSet GetAnAccountByIndex_TO_DataSet(int index)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE Oid={0}", index),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
//修改一行信息
public void UpdateAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"UPDATE owner SET name=N'{0}',sex='{1}',phone=N'{2}',buildnum=N'{3}',unit=N'{4}',roomnum=N'{5}' " +
"WHERE Oid={6}; ", name, sex, phone, buildNum, unit, roomNum, index),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
修改BLayer的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YYYDemo.P_DLayer;
using System.Data;
using System.Text.RegularExpressions;//正则表达式
using System.Runtime.InteropServices;//为了实现一个弹窗
namespace YYYDemo.P_BLayer
{
public class BLayer
{
//提示框,这两行照着写上即可,不必理解原理,会使用就行
[DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr handle, String message, String title, int type);
public DataSet GetAllAccount_TO_DataSet()
{
return new DLayer().GetAllAccount_TO_DataSet();
}
public void B_CloseConn()
{
new DLayer().D_CloseConn();
}
string errorStr = "";//这个也可以设置成局部变量,只不过让RegularCheck_Add(Update)_TO_Bool函数多传递一个参数而已。
//添加账户时正则表达式对输入数据的验证
private bool RegularCheck_Add_TO_Bool(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";//2-4个中文
string rStr_Phone = @"^\d{11}$";//11位数字
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";//1-3位数字
if (!Regex.IsMatch(name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(buildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(roomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
DataTable table = GetAllAccount_TO_DataSet().Tables[0];
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < table.Rows.Count; i++)
{
if (phone == table.Rows[i][3].ToString())
equal_Phone = true;
if (
buildNum == table.Rows[i][4].ToString() &&
unit == table.Rows[i][5].ToString() &&
roomNum == table.Rows[i][6].ToString()
)
equal_Position = true;
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
B_CloseConn();
return flag;
}
//添加一个账户
public string AddAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
if (RegularCheck_Add_TO_Bool(name, sex, phone, buildNum, unit, roomNum))
{
errorStr = "新增业主信息成功!";
new DLayer().AddAnAccount(name, sex, phone, buildNum, unit, roomNum);
}
else
errorStr += "\n新增业主信息失败!";
return errorStr;
}
//通过手机号获取该行数据的索引,为下面的GetAnAccountByIndex_TO_DataSet()函数提供作用
public int GetIndexByPhone_TO_Int(string phone)
{
return Convert.ToInt32(
new DLayer().GetAnAccountByPhone_TO_DataSet(phone).Tables[0].Rows[0][0].ToString());
}
//通过索引获取该行数据的全部信息,以DataSet数据类型返回
public DataSet GetAnAccountByIndex_TO_DataSet(int index)
{
return new DLayer().GetAnAccountByIndex_TO_DataSet(index);
}
//修改一个账户的信息
public string UpdateAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
if (RegularCheck_Update_TO_Bool(name, sex, phone, buildNum, unit, roomNum, index))
{
errorStr = "修改业主信息成功!";
new DLayer().UpdateAnAccount(name, sex, phone, buildNum, unit, roomNum, index);
}
else
errorStr += "\n修改业主信息失败!";
return errorStr;
}
//修改账户时正则表达式对输入数据的验证
//修改个人信息,需要验证 手机号 和 住房位置 是否 *跟别人* 重复;还需验证数据是否合理
private bool RegularCheck_Update_TO_Bool(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";
string rStr_Phone = @"^\d{11}$";
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";
if (!Regex.IsMatch(name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(buildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(roomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
DataTable table = GetAllAccount_TO_DataSet().Tables[0];
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < table.Rows.Count; i++)
{
if (Convert.ToInt32(table.Rows[i][0].ToString())
!= index)
{
if (phone == table.Rows[i][3].ToString())
equal_Phone = true;
if (
buildNum == table.Rows[i][4].ToString() &&
unit == table.Rows[i][5].ToString() &&
roomNum == table.Rows[i][6].ToString()
)
equal_Position = true;
}
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
B_CloseConn();
return flag;
}
}
}
修改ShowAll页面的GridView控件的事件,双击下图这两个事件处,让其自动添加两个方法。
为GridView添加两列ButtonField列。
可以看到这一列已经出来了。
继续编辑列。
将 修改 这一列的CommandName修改为Y_Update
可以在ShowALl.aspx页面的源码上看到如下图所示的代码:
截止目前,ShowAll.aspx的代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ShowAll.aspx.cs" Inherits="P_ULayer.ShowAll" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>小区业主列表</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="Div_lbl_Topic">
<asp:Label runat="server" ID="lbl_Topic" Text="小 区 业 主 列 表"></asp:Label>
</div>
<div>
<br /><br />
<asp:HyperLink Target="_self" NavigateUrl="~/AddAccount.aspx" runat="server" ID="hLink_AddAccount" Text="新增业主"></asp:HyperLink>
<br /><br /><br /><br />
</div>
<asp:GridView ID="gView" runat="server"
AllowPaging="True"
AutoGenerateColumns="False" OnPageIndexChanging="gView_PageIndexChanging" OnRowCommand="gView_RowCommand">
<Columns>
<asp:BoundField DataField="Name" HeaderText="姓名" SortExpression="Name" />
<asp:BoundField DataField="Sex" HeaderText="性别" />
<asp:BoundField DataField="Phone" HeaderText="联系电话" SortExpression="Phone" />
<asp:BoundField DataField="BuildNum" HeaderText="楼号" SortExpression="BuildNum" />
<asp:BoundField DataField="Unit" HeaderText="单元" SortExpression="Unit" />
<asp:BoundField DataField="RoomNum" HeaderText="房间号" SortExpression="RoomNum" />
<asp:ButtonField CommandName="Y_Update" HeaderText="操作" ShowHeader="True" Text="修改" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
继续修改ShowAll.aspx.cs的代码,在ShowAll页面上实现换页功能和跳转到AlterAccount页面的功能。
截止目前,ShowAll.aspx.cs的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using YYYDemo.P_BLayer;
namespace P_ULayer
{
public partial class ShowAll : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.gView.DataSource = new BLayer().GetAllAccount_TO_DataSet();
this.gView.DataBind();
new BLayer().B_CloseConn();
}
protected void gView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Y_Update" || e.CommandName == "Y_Delete")
{
//获取 操作列 或者 删除列 点击的是GridView的哪一行
int gViewSelect_Index = Convert.ToInt32(e.CommandArgument);
//将点击的这一行的手机号(因为手机号不可重复)的业主的Oid字段的值传给 全局变量 Application["Index"]
Application["Index"] = new BLayer().GetIndexByPhone_TO_Int(
this.gView.Rows[gViewSelect_Index].Cells[2].Text.ToString()
);
//这个代码块也就是实现了 : 点击的哪一行 ---> 手机号 ---> Oid ---> Application["Index"]
}
if (e.CommandName == "Y_Update")
Response.Redirect("AlterAccount.aspx");
if (e.CommandName == "Y_Delete")
{
//TODO
}
new BLayer().B_CloseConn();
}
protected void gView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
this.gView.PageIndex = e.NewPageIndex;
gView.DataBind();
}
}
}
修改AlterAccount.cs的代码:
运行测试:
没问题
2.11 实现删除业主信息功能
DLayer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace YYYDemo.P_DLayer
{
public class DLayer
{
//创建数据库连接
private SqlConnection CreateConnection()
{
return new SqlConnection(
"Data Source=DESKTOP-ADKCETM;Initial Catalog=Y_strong;Integrated Security=True"
);
}
//关闭连接
public void D_CloseConn()
{
CreateConnection().Close();
}
//获取全部的账户信息,以DataSet数据类型返回
public DataSet GetAllAccount_TO_DataSet()
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
"SELECT * FROM owner", conn
);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
//添加一个账户
public void AddAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"INSERT INTO owner(name,sex,phone,buildnum,unit,roomnum) " +
"VALUES(N'{0}','{1}',N'{2}',N'{3}',N'{4}',N'{5}')"
, name, sex, phone, buildNum, unit, roomNum),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
//通过手机号获得一个账户的信息,以DataSet数据类型返回;
//这个函数是为了在B层通过手机号获取账户的id
public DataSet GetAnAccountByPhone_TO_DataSet(string phone)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE phone=N'{0}'", phone),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
//通过id获得一个账户的信息,以DataSet数据类型返回
public DataSet GetAnAccountByIndex_TO_DataSet(int index)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE Oid={0}", index),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
//修改一行信息
public void UpdateAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"UPDATE owner SET name=N'{0}',sex='{1}',phone=N'{2}',buildnum=N'{3}',unit=N'{4}',roomnum=N'{5}' " +
"WHERE Oid={6}; ", name, sex, phone, buildNum, unit, roomNum, index),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
//删除一行信息
public void DeleteAnAccount(int index)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format("DELETE FROM owner WHERE Oid = {0}", index),
conn);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
BLayer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YYYDemo.P_DLayer;
using System.Data;
using System.Text.RegularExpressions;//正则表达式
using System.Runtime.InteropServices;//为了实现一个弹窗
namespace YYYDemo.P_BLayer
{
public class BLayer
{
//提示框,这两行照着写上即可,不必理解原理,会使用就行
[DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr handle, String message, String title, int type);
public DataSet GetAllAccount_TO_DataSet()
{
return new DLayer().GetAllAccount_TO_DataSet();
}
public void B_CloseConn()
{
new DLayer().D_CloseConn();
}
string errorStr = "";//这个也可以设置成局部变量,只不过让RegularCheck_Add(Update)_TO_Bool函数多传递一个参数而已。
//添加账户时正则表达式对输入数据的验证
private bool RegularCheck_Add_TO_Bool(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";//2-4个中文
string rStr_Phone = @"^\d{11}$";//11位数字
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";//1-3位数字
if (!Regex.IsMatch(name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(buildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(roomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
DataTable table = GetAllAccount_TO_DataSet().Tables[0];
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < table.Rows.Count; i++)
{
if (phone == table.Rows[i][3].ToString())
equal_Phone = true;
if (
buildNum == table.Rows[i][4].ToString() &&
unit == table.Rows[i][5].ToString() &&
roomNum == table.Rows[i][6].ToString()
)
equal_Position = true;
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
B_CloseConn();
return flag;
}
//添加一个账户
public string AddAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
if (RegularCheck_Add_TO_Bool(name, sex, phone, buildNum, unit, roomNum))
{
errorStr = "新增业主信息成功!";
new DLayer().AddAnAccount(name, sex, phone, buildNum, unit, roomNum);
}
else
errorStr += "\n新增业主信息失败!";
return errorStr;
}
//通过手机号获取该行数据的索引,为下面的GetAnAccountByIndex_TO_DataSet()函数提供作用
public int GetIndexByPhone_TO_Int(string phone)
{
return Convert.ToInt32(
new DLayer().GetAnAccountByPhone_TO_DataSet(phone).Tables[0].Rows[0][0].ToString());
}
//通过索引获取该行数据的全部信息,以DataSet数据类型返回
public DataSet GetAnAccountByIndex_TO_DataSet(int index)
{
return new DLayer().GetAnAccountByIndex_TO_DataSet(index);
}
//修改一个账户的信息
public string UpdateAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
if (RegularCheck_Update_TO_Bool(name, sex, phone, buildNum, unit, roomNum, index))
{
errorStr = "修改业主信息成功!";
new DLayer().UpdateAnAccount(name, sex, phone, buildNum, unit, roomNum, index);
}
else
errorStr += "\n修改业主信息失败!";
return errorStr;
}
//修改账户时正则表达式对输入数据的验证
//修改个人信息,需要验证 手机号 和 住房位置 是否 *跟别人* 重复;还需验证数据是否合理
private bool RegularCheck_Update_TO_Bool(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";
string rStr_Phone = @"^\d{11}$";
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";
if (!Regex.IsMatch(name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(buildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(roomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
DataTable table = GetAllAccount_TO_DataSet().Tables[0];
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < table.Rows.Count; i++)
{
if (Convert.ToInt32(table.Rows[i][0].ToString())
!= index)
{
if (phone == table.Rows[i][3].ToString())
equal_Phone = true;
if (
buildNum == table.Rows[i][4].ToString() &&
unit == table.Rows[i][5].ToString() &&
roomNum == table.Rows[i][6].ToString()
)
equal_Position = true;
}
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
B_CloseConn();
return flag;
}
//删除一个账户
public string DeleteAnAccount(int index)
{
errorStr = "删除业主信息成功!";
new DLayer().DeleteAnAccount(index);
return errorStr;
}
}
}
ShowAll.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ShowAll.aspx.cs" Inherits="P_ULayer.ShowAll" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>小区业主列表</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="Div_lbl_Topic">
<asp:Label runat="server" ID="lbl_Topic" Text="小 区 业 主 列 表"></asp:Label>
</div>
<div>
<br /><br />
<asp:HyperLink Target="_self" NavigateUrl="~/AddAccount.aspx" runat="server" ID="hLink_AddAccount" Text="新增业主"></asp:HyperLink>
<br /><br /><br /><br />
</div>
<asp:GridView ID="gView" runat="server"
AllowPaging="True"
AutoGenerateColumns="False" OnPageIndexChanging="gView_PageIndexChanging" OnRowCommand="gView_RowCommand">
<Columns>
<asp:BoundField DataField="Name" HeaderText="姓名" SortExpression="Name" />
<asp:BoundField DataField="Sex" HeaderText="性别" />
<asp:BoundField DataField="Phone" HeaderText="联系电话" SortExpression="Phone" />
<asp:BoundField DataField="BuildNum" HeaderText="楼号" SortExpression="BuildNum" />
<asp:BoundField DataField="Unit" HeaderText="单元" SortExpression="Unit" />
<asp:BoundField DataField="RoomNum" HeaderText="房间号" SortExpression="RoomNum" />
<asp:ButtonField CommandName="Y_Update" HeaderText="操作" ShowHeader="True" Text="修改" />
<asp:ButtonField CommandName="Y_Delete" HeaderText="操作" ShowHeader="True" Text="删除" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
修改ShowAll.aspx.cs的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using YYYDemo.P_BLayer;
namespace P_ULayer
{
public partial class ShowAll : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.gView.DataSource = new BLayer().GetAllAccount_TO_DataSet();
this.gView.DataBind();
new BLayer().B_CloseConn();
}
protected void gView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Y_Update" || e.CommandName == "Y_Delete")
{
//获取 操作列 或者 删除列 点击的是GridView的哪一行
int gViewSelect_Index = Convert.ToInt32(e.CommandArgument);
//将点击的这一行的手机号(因为手机号不可重复)的业主的Oid字段的值传给 全局变量 Application["Index"]
Application["Index"] = new BLayer().GetIndexByPhone_TO_Int(
this.gView.Rows[gViewSelect_Index].Cells[2].Text.ToString()
);
//这个代码块也就是实现了 : 点击的哪一行 ---> 手机号 ---> Oid ---> Application["Index"]
}
if (e.CommandName == "Y_Update")
Response.Redirect("AlterAccount.aspx");
if (e.CommandName == "Y_Delete")
{
if (BtnDelete() == 1)
{
new BLayer().DeleteAnAccount(Convert.ToInt32(Application["Index"]));
Response.Redirect("ShowAll.aspx");
}
}
new BLayer().B_CloseConn();
}
protected void gView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
this.gView.PageIndex = e.NewPageIndex;
gView.DataBind();
}
private int BtnDelete()
{
return BLayer.MessageBox(IntPtr.Zero, "确定要删除这条数据吗?", "警告!", 1);
}
}
}
运行测试:
我这里先随便添加了多条数据:
可以看到,换页功能正常:
下面进行进行删除操作:
正常
分割线一
截止到现在,已经完成了SQLserver数据库上的增删改查,样式表我还没怎么添加,好像只是给修改和删除页面的TextBox添加了一个字体大小为16pt的样式。
接下来的部分我会添加样式表和样式,并且完成连接MySQL的操作。
可能还会添加实体类和对不同数据库的支持,主题和皮肤功能也在预定之列吧。或许还会添加一个头像。
以上内容完成后的当前时间:2019年5月22日00:32:39
2.12 添加实体类,替代DataSet传递数据
新建一个Entity类库项目
修改Entity项目的程序集名称和默认命名空间名称
并添加一个Owner类
编辑Owner.cs的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace YYYDemo.Entity
{
public class Owner
{
private int oid;
private string name;
private char sex;
private string phone;
private string buildNum;
private string unit;
private string roomNum;
public int Oid
{
set { oid = value; }
get { return oid; }
}
public string Name
{
set { name = value; }
get { return name; }
}
public char Sex
{
set { sex = value; }
get { return sex; }
}
public string Phone
{
set { phone = value; }
get { return phone; }
}
public string BuildNum
{
set { buildNum = value; }
get { return buildNum; }
}
public string Unit
{
set { unit = value; }
get { return unit; }
}
public string RoomNum
{
set { roomNum = value; }
get { return roomNum; }
}
}
}
添加引用,添加完后应该是下图所示的情况:
修改D层的P_DLayer项目的DLayer类
修改B层的P_BLayer项目的BLayer类
修改U层的P_ULayer项目的ShowAll.aspx.cs
修改U层的P_ULayer项目的AlterAccount.aspx.cs 的代码
运行测试,发现没问题。
2.13 目前的代码
1. 未删减多余代码时:
DLayer.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using YYYDemo.Entity;
namespace YYYDemo.P_DLayer
{
public class DLayer
{
//创建数据库连接
private SqlConnection CreateConnection()
{
return new SqlConnection(
"Data Source=DESKTOP-ADKCETM;Initial Catalog=Y_strong;Integrated Security=True"
);
}
//关闭连接
public void D_CloseConn()
{
CreateConnection().Close();
}
//获取全部的账户信息,以DataSet数据类型返回
public DataSet GetAllAccount_TO_DataSet()
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
"SELECT * FROM owner", conn
);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
public IList<Owner> GetAllAccount()
{
List<Owner> owners = new List<Owner>();
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
"SELECT * FROM owner", conn
);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
for (int i = 0; i < dSet.Tables[0].Rows.Count; i++)
{
Owner owner = new Owner();
owner.Oid = Convert.ToInt32(dSet.Tables[0].Rows[i][0].ToString());
owner.Name = dSet.Tables[0].Rows[i][1].ToString();
owner.Sex = Convert.ToChar(dSet.Tables[0].Rows[i][2].ToString());
owner.Phone = dSet.Tables[0].Rows[i][3].ToString();
owner.BuildNum = dSet.Tables[0].Rows[i][4].ToString();
owner.Unit = dSet.Tables[0].Rows[i][5].ToString();
owner.RoomNum = dSet.Tables[0].Rows[i][6].ToString();
owners.Add(owner);
}
conn.Close();
return owners;
}
//添加一个账户
public void AddAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"INSERT INTO owner(name,sex,phone,buildnum,unit,roomnum) " +
"VALUES(N'{0}','{1}',N'{2}',N'{3}',N'{4}',N'{5}')"
, name, sex, phone, buildNum, unit, roomNum),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
//通过手机号获得一个账户的信息,以DataSet数据类型返回;
//这个函数是为了在B层通过手机号获取账户的id
public DataSet GetAnAccountByPhone_TO_DataSet(string phone)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE phone=N'{0}'", phone),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
public Owner GetAnAccountByPhone_TO_Owner(string phone)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE phone=N'{0}'", phone),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
Owner owner = new Owner();
owner.Oid = Convert.ToInt32(dSet.Tables[0].Rows[0][0].ToString());
owner.Name = dSet.Tables[0].Rows[0][1].ToString();
owner.Sex = Convert.ToChar(dSet.Tables[0].Rows[0][2].ToString());
owner.Phone = dSet.Tables[0].Rows[0][3].ToString();
owner.BuildNum = dSet.Tables[0].Rows[0][4].ToString();
owner.Unit = dSet.Tables[0].Rows[0][5].ToString();
owner.RoomNum = dSet.Tables[0].Rows[0][6].ToString();
conn.Close();
return owner;
}
//通过id获得一个账户的信息,以DataSet数据类型返回
public DataSet GetAnAccountByIndex_TO_DataSet(int index)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE Oid={0}", index),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
return dSet;
}
public Owner GetAnAccountByIndex_TO_Owner(int index)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE Oid={0}", index),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
Owner owner = new Owner();
owner.Oid = Convert.ToInt32(dSet.Tables[0].Rows[0][0].ToString());
owner.Name = dSet.Tables[0].Rows[0][1].ToString();
owner.Sex = Convert.ToChar(dSet.Tables[0].Rows[0][2].ToString());
owner.Phone = dSet.Tables[0].Rows[0][3].ToString();
owner.BuildNum = dSet.Tables[0].Rows[0][4].ToString();
owner.Unit = dSet.Tables[0].Rows[0][5].ToString();
owner.RoomNum = dSet.Tables[0].Rows[0][6].ToString();
conn.Close();
return owner;
}
//修改一行信息
public void UpdateAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"UPDATE owner SET name=N'{0}',sex='{1}',phone=N'{2}',buildnum=N'{3}',unit=N'{4}',roomnum=N'{5}' " +
"WHERE Oid={6}; ", name, sex, phone, buildNum, unit, roomNum, index),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
//删除一行信息
public void DeleteAnAccount(int index)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format("DELETE FROM owner WHERE Oid = {0}", index),
conn);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
BLayer:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YYYDemo.P_DLayer;
using System.Data;
using System.Text.RegularExpressions;//正则表达式
using System.Runtime.InteropServices;//为了实现一个弹窗
using YYYDemo.Entity;
namespace YYYDemo.P_BLayer
{
public class BLayer
{
//提示框,这两行照着写上即可,不必理解原理,会使用就行
[DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr handle, String message, String title, int type);
public DataSet GetAllAccount_TO_DataSet()
{
return new DLayer().GetAllAccount_TO_DataSet();
}
public IList<Owner> GetAllAccount()
{
return new DLayer().GetAllAccount();
}
public void B_CloseConn()
{
new DLayer().D_CloseConn();
}
string errorStr = "";//这个也可以设置成局部变量,只不过让RegularCheck_Add(Update)_TO_Bool函数多传递一个参数而已。
//添加账户时正则表达式对输入数据的验证
private bool RegularCheck_Add_TO_Bool(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";//2-4个中文
string rStr_Phone = @"^\d{11}$";//11位数字
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";//1-3位数字
if (!Regex.IsMatch(name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(buildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(roomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
var owners = GetAllAccount();
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < owners.Count; i++)
{
if (phone == owners[i].Phone)
equal_Phone = true;
if (
buildNum == owners[i].BuildNum &&
unit == owners[i].Unit &&
roomNum == owners[i].RoomNum
)
equal_Position = true;
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
return flag;
}
//添加一个账户
public string AddAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
if (RegularCheck_Add_TO_Bool(name, sex, phone, buildNum, unit, roomNum))
{
errorStr = "新增业主信息成功!";
new DLayer().AddAnAccount(name, sex, phone, buildNum, unit, roomNum);
}
else
errorStr += "\n新增业主信息失败!";
return errorStr;
}
//通过手机号获取该行数据的索引,在U层中为下面的GetAnAccountByIndex_TO_DataSet()函数提供作用
public int GetIndexByPhone_TO_Int(string phone)
{
return Convert.ToInt32(
new DLayer().GetAnAccountByPhone_TO_Owner(phone).Oid);
//return Convert.ToInt32(
//new DLayer().GetAnAccountByPhone_TO_DataSet(phone).Tables[0].Rows[0][0].ToString());
}
//通过索引获取该行数据的全部信息,以DataSet数据类型返回
public DataSet GetAnAccountByIndex_TO_DataSet(int index)
{
return new DLayer().GetAnAccountByIndex_TO_DataSet(index);
}
public Owner GetAnAccountBydIndex_TO_Owner(int index)
{
return new DLayer().GetAnAccountByIndex_TO_Owner(index);
}
//修改一个账户的信息
public string UpdateAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
if (RegularCheck_Update_TO_Bool(name, sex, phone, buildNum, unit, roomNum, index))
{
errorStr = "修改业主信息成功!";
new DLayer().UpdateAnAccount(name, sex, phone, buildNum, unit, roomNum, index);
}
else
errorStr += "\n修改业主信息失败!";
return errorStr;
}
//修改账户时正则表达式对输入数据的验证
//修改个人信息,需要验证 手机号 和 住房位置 是否 *跟别人* 重复;还需验证数据是否合理
private bool RegularCheck_Update_TO_Bool(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";
string rStr_Phone = @"^\d{11}$";
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";
if (!Regex.IsMatch(name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(buildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(roomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
var owners = GetAllAccount();
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < owners.Count; i++)
{
if (owners[i].Oid != index)
{
if (phone == owners[i].Phone)
equal_Phone = true;
if (
buildNum == owners[i].BuildNum &&
unit == owners[i].Unit &&
roomNum == owners[i].RoomNum
)
equal_Position = true;
}
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
return flag;
}
//删除一个账户
public string DeleteAnAccount(int index)
{
errorStr = "删除业主信息成功!";
new DLayer().DeleteAnAccount(index);
return errorStr;
}
}
}
ShowAll.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using YYYDemo.P_BLayer;
namespace P_ULayer
{
public partial class ShowAll : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.gView.DataSource = new BLayer().GetAllAccount();
this.gView.DataBind();
}
protected void gView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Y_Update" || e.CommandName == "Y_Delete")
{
//获取 操作列 或者 删除列 点击的是GridView的哪一行
int gViewSelect_Index = Convert.ToInt32(e.CommandArgument);
//将点击的这一行的手机号(因为手机号不可重复)的业主的Oid字段的值传给 全局变量 Application["Index"]
Application["Index"] = new BLayer().GetIndexByPhone_TO_Int(
this.gView.Rows[gViewSelect_Index].Cells[2].Text.ToString()
);
//这个代码块也就是实现了 : 点击的哪一行 ---> 手机号 ---> Oid ---> Application["Index"]
}
if (e.CommandName == "Y_Update")
Response.Redirect("AlterAccount.aspx");
if (e.CommandName == "Y_Delete")
{
if (BtnDelete() == 1)
{
new BLayer().DeleteAnAccount(Convert.ToInt32(Application["Index"]));
Response.Redirect("ShowAll.aspx");
}
}
}
protected void gView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
this.gView.PageIndex = e.NewPageIndex;
gView.DataBind();
}
private int BtnDelete()
{
return BLayer.MessageBox(IntPtr.Zero, "确定要删除这条数据吗?", "警告!", 1);
}
}
}
Alteraccount.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
//using System.Data;
using YYYDemo.P_BLayer;
using YYYDemo.Entity;
namespace YYYDemo.P_ULayer
{
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//这里若不加此判断,则每次点击未修改成功的按钮后,页面都会重传,然后恢复一开始的值,不会保存修改的值
if (!IsPostBack)
{
Owner owner = new BLayer().GetAnAccountBydIndex_TO_Owner(Convert.ToInt32(Application["Index"]));
(Master.FindControl("textBox_Name") as TextBox).Text = owner.Name;
if (owner.Sex == '男')
(Master.FindControl("radioBtn_Boy") as RadioButton).Checked = true;
if (owner.Sex == '女')
(Master.FindControl("radioBtn_Girl") as RadioButton).Checked = true;
(Master.FindControl("textBox_Phone") as TextBox).Text = owner.Phone;
(Master.FindControl("textBox_BuildNum") as TextBox).Text = owner.BuildNum;
(Master.FindControl("textBox_Unit") as TextBox).Text = owner.Unit;
(Master.FindControl("textBox_RoomNum") as TextBox).Text = owner.RoomNum;
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
char sex = '男';
if ((Master.FindControl("radioBtn_Girl") as RadioButton).Checked)
sex = '女';
string message = new BLayer().UpdateAnAccount(
(Master.FindControl("textBox_Name") as TextBox).Text.ToString(),
sex,
(Master.FindControl("textBox_Phone") as TextBox).Text.ToString(),
(Master.FindControl("textBox_BuildNum") as TextBox).Text.ToString(),
(Master.FindControl("textBox_Unit") as TextBox).Text.ToString(),
(Master.FindControl("textBox_RoomNum") as TextBox).Text.ToString(),
Convert.ToInt32(Application["index"])
);
BLayer.MessageBox(IntPtr.Zero, message, "提示!", 0);
}
}
}
2. 删减多余代码后:
DLayer.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using YYYDemo.Entity;
namespace YYYDemo.P_DLayer
{
public class DLayer
{
//创建数据库连接
private SqlConnection CreateConnection()
{
return new SqlConnection(
"Data Source=DESKTOP-ADKCETM;Initial Catalog=Y_strong;Integrated Security=True"
);
}
//获取全部的账户信息,以Owner实体类类型返回
public IList<Owner> GetAllAccount()
{
List<Owner> owners = new List<Owner>();
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
"SELECT * FROM owner", conn
);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
for (int i = 0; i < dSet.Tables[0].Rows.Count; i++)
{
Owner owner = new Owner();
owner.Oid = Convert.ToInt32(dSet.Tables[0].Rows[i][0].ToString());
owner.Name = dSet.Tables[0].Rows[i][1].ToString();
owner.Sex = Convert.ToChar(dSet.Tables[0].Rows[i][2].ToString());
owner.Phone = dSet.Tables[0].Rows[i][3].ToString();
owner.BuildNum = dSet.Tables[0].Rows[i][4].ToString();
owner.Unit = dSet.Tables[0].Rows[i][5].ToString();
owner.RoomNum = dSet.Tables[0].Rows[i][6].ToString();
owners.Add(owner);
}
conn.Close();
return owners;
}
//添加一个账户
public void AddAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"INSERT INTO owner(name,sex,phone,buildnum,unit,roomnum) " +
"VALUES(N'{0}','{1}',N'{2}',N'{3}',N'{4}',N'{5}')"
, name, sex, phone, buildNum, unit, roomNum),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
//通过手机号获得一个账户的信息,以Owner实体类类型返回;
//这个函数是为了在B层通过手机号获取账户的id
public Owner GetAnAccountByPhone_TO_Owner(string phone)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE phone=N'{0}'", phone),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
Owner owner = new Owner();
owner.Oid = Convert.ToInt32(dSet.Tables[0].Rows[0][0].ToString());
owner.Name = dSet.Tables[0].Rows[0][1].ToString();
owner.Sex = Convert.ToChar(dSet.Tables[0].Rows[0][2].ToString());
owner.Phone = dSet.Tables[0].Rows[0][3].ToString();
owner.BuildNum = dSet.Tables[0].Rows[0][4].ToString();
owner.Unit = dSet.Tables[0].Rows[0][5].ToString();
owner.RoomNum = dSet.Tables[0].Rows[0][6].ToString();
conn.Close();
return owner;
}
//通过id获得一个账户的信息,以Owner实体类类型返回
public Owner GetAnAccountByIndex_TO_Owner(int index)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE Oid={0}", index),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
Owner owner = new Owner();
owner.Oid = Convert.ToInt32(dSet.Tables[0].Rows[0][0].ToString());
owner.Name = dSet.Tables[0].Rows[0][1].ToString();
owner.Sex = Convert.ToChar(dSet.Tables[0].Rows[0][2].ToString());
owner.Phone = dSet.Tables[0].Rows[0][3].ToString();
owner.BuildNum = dSet.Tables[0].Rows[0][4].ToString();
owner.Unit = dSet.Tables[0].Rows[0][5].ToString();
owner.RoomNum = dSet.Tables[0].Rows[0][6].ToString();
conn.Close();
return owner;
}
//修改一行信息
public void UpdateAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"UPDATE owner SET name=N'{0}',sex='{1}',phone=N'{2}',buildnum=N'{3}',unit=N'{4}',roomnum=N'{5}' " +
"WHERE Oid={6}; ", name, sex, phone, buildNum, unit, roomNum, index),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
//删除一行信息
public void DeleteAnAccount(int index)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format("DELETE FROM owner WHERE Oid = {0}", index),
conn);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
BLayer.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YYYDemo.P_DLayer;
using System.Text.RegularExpressions;//正则表达式
using System.Runtime.InteropServices;//为了实现一个弹窗
using YYYDemo.Entity;
namespace YYYDemo.P_BLayer
{
public class BLayer
{
//提示框,这两行照着写上即可,不必理解原理,会使用就行
[DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr handle, String message, String title, int type);
public IList<Owner> GetAllAccount()
{
return new DLayer().GetAllAccount();
}
string errorStr = "";//这个也可以设置成局部变量,只不过让RegularCheck_Add(Update)_TO_Bool函数多传递一个参数而已。
//添加账户时正则表达式对输入数据的验证
private bool RegularCheck_Add_TO_Bool(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";//2-4个中文
string rStr_Phone = @"^\d{11}$";//11位数字
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";//1-3位数字
if (!Regex.IsMatch(name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(buildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(roomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
var owners = GetAllAccount();
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < owners.Count; i++)
{
if (phone == owners[i].Phone)
equal_Phone = true;
if (
buildNum == owners[i].BuildNum &&
unit == owners[i].Unit &&
roomNum == owners[i].RoomNum
)
equal_Position = true;
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
return flag;
}
//添加一个账户
public string AddAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum)
{
if (RegularCheck_Add_TO_Bool(name, sex, phone, buildNum, unit, roomNum))
{
errorStr = "新增业主信息成功!";
new DLayer().AddAnAccount(name, sex, phone, buildNum, unit, roomNum);
}
else
errorStr += "\n新增业主信息失败!";
return errorStr;
}
//通过手机号获取该行数据的索引,在U层中为下面的GetAnAccountByIndex_TO_DataSet()函数提供作用
public int GetIndexByPhone_TO_Int(string phone)
{
return Convert.ToInt32(
new DLayer().GetAnAccountByPhone_TO_Owner(phone).Oid);
}
//通过索引获取该行数据的全部信息,以Owner实体类类型返回
public Owner GetAnAccountBydIndex_TO_Owner(int index)
{
return new DLayer().GetAnAccountByIndex_TO_Owner(index);
}
//修改一个账户的信息
public string UpdateAnAccount(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
if (RegularCheck_Update_TO_Bool(name, sex, phone, buildNum, unit, roomNum, index))
{
errorStr = "修改业主信息成功!";
new DLayer().UpdateAnAccount(name, sex, phone, buildNum, unit, roomNum, index);
}
else
errorStr += "\n修改业主信息失败!";
return errorStr;
}
//修改账户时正则表达式对输入数据的验证
//修改个人信息,需要验证 手机号 和 住房位置 是否 *跟别人* 重复;还需验证数据是否合理
private bool RegularCheck_Update_TO_Bool(string name, char sex, string phone, string buildNum, string unit, string roomNum, int index)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";
string rStr_Phone = @"^\d{11}$";
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";
if (!Regex.IsMatch(name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(buildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(roomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
var owners = GetAllAccount();
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < owners.Count; i++)
{
if (owners[i].Oid != index)
{
if (phone == owners[i].Phone)
equal_Phone = true;
if (
buildNum == owners[i].BuildNum &&
unit == owners[i].Unit &&
roomNum == owners[i].RoomNum
)
equal_Position = true;
}
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
return flag;
}
//删除一个账户
public string DeleteAnAccount(int index)
{
errorStr = "删除业主信息成功!";
new DLayer().DeleteAnAccount(index);
return errorStr;
}
}
}
ShowAll.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using YYYDemo.P_BLayer;
namespace P_ULayer
{
public partial class ShowAll : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.gView.DataSource = new BLayer().GetAllAccount();
this.gView.DataBind();
}
protected void gView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Y_Update" || e.CommandName == "Y_Delete")
{
//获取 操作列 或者 删除列 点击的是GridView的哪一行
int gViewSelect_Index = Convert.ToInt32(e.CommandArgument);
//将点击的这一行的手机号(因为手机号不可重复)的业主的Oid字段的值传给 全局变量 Application["Index"]
Application["Index"] = new BLayer().GetIndexByPhone_TO_Int(
this.gView.Rows[gViewSelect_Index].Cells[2].Text.ToString()
);
//这个代码块也就是实现了 : 点击的哪一行 ---> 手机号 ---> Oid ---> Application["Index"]
}
if (e.CommandName == "Y_Update")
Response.Redirect("AlterAccount.aspx");
if (e.CommandName == "Y_Delete")
{
if (BtnDelete() == 1)
{
new BLayer().DeleteAnAccount(Convert.ToInt32(Application["Index"]));
Response.Redirect("ShowAll.aspx");
}
}
}
protected void gView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
this.gView.PageIndex = e.NewPageIndex;
gView.DataBind();
}
private int BtnDelete()
{
return BLayer.MessageBox(IntPtr.Zero, "确定要删除这条数据吗?", "警告!", 1);
}
}
}
AlterAccount.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using YYYDemo.P_BLayer;
using YYYDemo.Entity;
namespace YYYDemo.P_ULayer
{
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//这里若不加此判断,则每次点击未修改成功的按钮后,页面都会重传,然后恢复一开始的值,不会保存修改的值
if (!IsPostBack)
{
Owner owner = new BLayer().GetAnAccountBydIndex_TO_Owner(Convert.ToInt32(Application["Index"]));
(Master.FindControl("textBox_Name") as TextBox).Text = owner.Name;
if (owner.Sex == '男')
(Master.FindControl("radioBtn_Boy") as RadioButton).Checked = true;
if (owner.Sex == '女')
(Master.FindControl("radioBtn_Girl") as RadioButton).Checked = true;
(Master.FindControl("textBox_Phone") as TextBox).Text = owner.Phone;
(Master.FindControl("textBox_BuildNum") as TextBox).Text = owner.BuildNum;
(Master.FindControl("textBox_Unit") as TextBox).Text = owner.Unit;
(Master.FindControl("textBox_RoomNum") as TextBox).Text = owner.RoomNum;
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
char sex = '男';
if ((Master.FindControl("radioBtn_Girl") as RadioButton).Checked)
sex = '女';
string message = new BLayer().UpdateAnAccount(
(Master.FindControl("textBox_Name") as TextBox).Text.ToString(),
sex,
(Master.FindControl("textBox_Phone") as TextBox).Text.ToString(),
(Master.FindControl("textBox_BuildNum") as TextBox).Text.ToString(),
(Master.FindControl("textBox_Unit") as TextBox).Text.ToString(),
(Master.FindControl("textBox_RoomNum") as TextBox).Text.ToString(),
Convert.ToInt32(Application["index"])
);
BLayer.MessageBox(IntPtr.Zero, message, "提示!", 0);
}
}
}
运行测试,都正常
注:
- 添加实体类后,修改DLayer的代码,是将以DataSet为返回值的函数作为想要修改的函数去修改
- 修改完代码后,要保证,除了在D层的DLayer代码有 System.Data 的引用后,其余各层均没有
把多余的Class1删掉,现在的结构是下图所示:
在不适用实体类的时候,GridView的列的DataField的值必须对应数据表中的字段的名称,若数据表的结构修改,则程序会报错。
现在使用上了实体类之后,U层的GridView 的列的DataField 的值是对应了实体类的属性名称,这里虽然没变,是因为我在设计实体类的时候,写实体类的属性名称是仿照着数据表的字段名称来的,所以这里的DataField的值虽然没变,但是其实是已经映射到了实体类的属性名称上,而不是数据表的字段名称上。
也就是说,比如我将实体类的Name属性的名称修改为MMMM,然后在DLayer和AlterAccount页面上用到该实体类的Name属性的地方全部修改为MMMM,最后将ShowAll页面的GridView的某一列的DataField属性的值设置为MMMM,则程序正常运行。
2.14 继续修改代码,将D层的新增和修改函数的形参修改为Owner实体类对象
D层项目:
将一连串的形参修改为了一个Owner类型的形参
B层项目:
同样的,修改B层的AlterAccount函数,也是需要像AddAccount函数一样去改变形参。
接下来就不上图了,直接放B层和D层目前的代码。
B层BLayer:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YYYDemo.P_DLayer;
using System.Text.RegularExpressions;//正则表达式
using System.Runtime.InteropServices;//为了实现一个弹窗
using YYYDemo.Entity;
namespace YYYDemo.P_BLayer
{
public class BLayer
{
//提示框,这两行照着写上即可,不必理解原理,会使用就行
[DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr handle, String message, String title, int type);
public IList<Owner> GetAllAccount()
{
return new DLayer().GetAllAccount();
}
string errorStr = "";//这个也可以设置成局部变量,只不过让RegularCheck_Add(Update)_TO_Bool函数多传递一个参数而已。
//添加账户时正则表达式对输入数据的验证
private bool RegularCheck_Add_TO_Bool(Owner _owner)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";//2-4个中文
string rStr_Phone = @"^\d{11}$";//11位数字
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";//1-3位数字
if (!Regex.IsMatch(_owner.Name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(_owner.Phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(_owner.BuildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(_owner.Unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(_owner.RoomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
var owners = GetAllAccount();
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < owners.Count; i++)
{
if (_owner.Phone == owners[i].Phone)
equal_Phone = true;
if (
_owner.BuildNum == owners[i].BuildNum &&
_owner.Unit == owners[i].Unit &&
_owner.RoomNum == owners[i].RoomNum
)
equal_Position = true;
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
return flag;
}
//添加一个账户
public string AddAnAccount(Owner owner)
{
if (RegularCheck_Add_TO_Bool(owner))
{
errorStr = "新增业主信息成功!";
new DLayer().AddAnAccount(owner);
}
else
errorStr += "\n新增业主信息失败!";
return errorStr;
}
//通过手机号获取该行数据的索引,在U层中为下面的GetAnAccountByIndex_TO_DataSet()函数提供作用
public int GetIndexByPhone_TO_Int(string phone)
{
return Convert.ToInt32(
new DLayer().GetAnAccountByPhone_TO_Owner(phone).Oid);
}
//通过索引获取该行数据的全部信息,以Owner实体类类型返回
public Owner GetAnAccountBydIndex_TO_Owner(int index)
{
return new DLayer().GetAnAccountByIndex_TO_Owner(index);
}
//修改账户时正则表达式对输入数据的验证
//修改个人信息,需要验证 手机号 和 住房位置 是否 *跟别人* 重复;还需验证数据是否合理
private bool RegularCheck_Update_TO_Bool(Owner _owner)
{
errorStr = "";
bool flag = true;
string rStr_Name = "^[\u4e00-\u9fa5]{2,4}$";
string rStr_Phone = @"^\d{11}$";
string rStr_BuildNum_Unit_RoomNum = @"^\d{1,3}$";
if (!Regex.IsMatch(_owner.Name, rStr_Name))
{
errorStr += "姓名应为2-4个汉字!\n";
flag = false;
}
if (!Regex.IsMatch(_owner.Phone, rStr_Phone))
{
errorStr += "号码应为11位数字!\n";
flag = false;
}
if (!Regex.IsMatch(_owner.BuildNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "楼号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(_owner.Unit, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "单元号应为1-3位数字!\n";
flag = false;
}
if (!Regex.IsMatch(_owner.RoomNum, rStr_BuildNum_Unit_RoomNum))
{
errorStr += "房间号应为1-3位数字!\n";
flag = false;
}
var owners = GetAllAccount();
bool equal_Phone = false;
bool equal_Position = false;
for (int i = 0; i < owners.Count; i++)
{
if (owners[i].Oid != _owner.Oid)
{
if (_owner.Phone == owners[i].Phone)
equal_Phone = true;
if (
_owner.BuildNum == owners[i].BuildNum &&
_owner.Unit == owners[i].Unit &&
_owner.RoomNum == owners[i].RoomNum
)
equal_Position = true;
}
}
if (equal_Phone)
{
errorStr += "联系电话不能重复!\n";
flag = false;
}
if (equal_Position)
{
errorStr += "住房位置不能重复!\n";
flag = false;
}
return flag;
}
//修改一个账户的信息
public string UpdateAnAccount(Owner owner)
{
if (RegularCheck_Update_TO_Bool(owner))
{
errorStr = "修改业主信息成功!";
new DLayer().UpdateAnAccount(owner);
}
else
errorStr += "\n修改业主信息失败!";
return errorStr;
}
//删除一个账户
public string DeleteAnAccount(int index)
{
errorStr = "删除业主信息成功!";
new DLayer().DeleteAnAccount(index);
return errorStr;
}
}
}
D层DLayer:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using YYYDemo.Entity;
namespace YYYDemo.P_DLayer
{
public class DLayer
{
//创建数据库连接
private SqlConnection CreateConnection()
{
return new SqlConnection(
"Data Source=DESKTOP-ADKCETM;Initial Catalog=Y_strong;Integrated Security=True"
);
}
//获取全部的账户信息,以Owner实体类类型返回
public IList<Owner> GetAllAccount()
{
List<Owner> owners = new List<Owner>();
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
"SELECT * FROM owner", conn
);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
for (int i = 0; i < dSet.Tables[0].Rows.Count; i++)
{
Owner owner = new Owner();
owner.Oid = Convert.ToInt32(dSet.Tables[0].Rows[i][0].ToString());
owner.Name = dSet.Tables[0].Rows[i][1].ToString();
owner.Sex = Convert.ToChar(dSet.Tables[0].Rows[i][2].ToString());
owner.Phone = dSet.Tables[0].Rows[i][3].ToString();
owner.BuildNum = dSet.Tables[0].Rows[i][4].ToString();
owner.Unit = dSet.Tables[0].Rows[i][5].ToString();
owner.RoomNum = dSet.Tables[0].Rows[i][6].ToString();
owners.Add(owner);
}
conn.Close();
return owners;
}
//添加一个账户
public void AddAnAccount(Owner owner)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"INSERT INTO owner(name,sex,phone,buildnum,unit,roomnum) " +
"VALUES(N'{0}','{1}',N'{2}',N'{3}',N'{4}',N'{5}')"
, owner.Name, owner.Sex, owner.Phone, owner.BuildNum, owner.Unit, owner.RoomNum),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
//通过手机号获得一个账户的信息,以Owner实体类类型返回;
//这个函数是为了在B层通过手机号获取账户的id
public Owner GetAnAccountByPhone_TO_Owner(string phone)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE phone=N'{0}'", phone),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
Owner owner = new Owner();
owner.Oid = Convert.ToInt32(dSet.Tables[0].Rows[0][0].ToString());
owner.Name = dSet.Tables[0].Rows[0][1].ToString();
owner.Sex = Convert.ToChar(dSet.Tables[0].Rows[0][2].ToString());
owner.Phone = dSet.Tables[0].Rows[0][3].ToString();
owner.BuildNum = dSet.Tables[0].Rows[0][4].ToString();
owner.Unit = dSet.Tables[0].Rows[0][5].ToString();
owner.RoomNum = dSet.Tables[0].Rows[0][6].ToString();
conn.Close();
return owner;
}
//通过id获得一个账户的信息,以Owner实体类类型返回
public Owner GetAnAccountByIndex_TO_Owner(int index)
{
SqlConnection conn = CreateConnection();
conn.Open();
SqlDataAdapter dAdp = new SqlDataAdapter(
string.Format("SELECT * FROM owner WHERE Oid={0}", index),
conn);
DataSet dSet = new DataSet();
dAdp.Fill(dSet, "owner");
Owner owner = new Owner();
owner.Oid = Convert.ToInt32(dSet.Tables[0].Rows[0][0].ToString());
owner.Name = dSet.Tables[0].Rows[0][1].ToString();
owner.Sex = Convert.ToChar(dSet.Tables[0].Rows[0][2].ToString());
owner.Phone = dSet.Tables[0].Rows[0][3].ToString();
owner.BuildNum = dSet.Tables[0].Rows[0][4].ToString();
owner.Unit = dSet.Tables[0].Rows[0][5].ToString();
owner.RoomNum = dSet.Tables[0].Rows[0][6].ToString();
conn.Close();
return owner;
}
//修改一行信息
public void UpdateAnAccount(Owner owner)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format(
"UPDATE owner SET name=N'{0}',sex='{1}',phone=N'{2}',buildnum=N'{3}',unit=N'{4}',roomnum=N'{5}' " +
"WHERE Oid={6}; ", owner.Name, owner.Sex, owner.Phone, owner.BuildNum, owner.Unit, owner.RoomNum, owner.Oid),
conn
);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
//删除一行信息
public void DeleteAnAccount(int index)
{
SqlConnection conn = CreateConnection();
SqlCommand cmd = new SqlCommand(
string.Format("DELETE FROM owner WHERE Oid = {0}", index),
conn);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
修改U层的新增和修改部分的代码:
AddAccount.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using YYYDemo.P_BLayer;
using YYYDemo.Entity;
namespace YYYDemo.P_ULayer
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
char sex = '男';
if ((Master.FindControl("radioBtn_Girl") as RadioButton).Checked)
sex = '女';
Owner owner = new Owner();
owner.Name = (Master.FindControl("textBox_Name") as TextBox).Text.ToString();
owner.Sex = sex;
owner.Phone = (Master.FindControl("textBox_Phone") as TextBox).Text.ToString();
owner.BuildNum = (Master.FindControl("textBox_BuildNum") as TextBox).Text.ToString();
owner.Unit = (Master.FindControl("textBox_Unit") as TextBox).Text.ToString();
owner.RoomNum = (Master.FindControl("textBox_RoomNum") as TextBox).Text.ToString();
string message = new BLayer().AddAnAccount(owner);
BLayer.MessageBox(IntPtr.Zero, message, "提示!", 0);
}
}
}
AlterAccount.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using YYYDemo.P_BLayer;
using YYYDemo.Entity;
namespace YYYDemo.P_ULayer
{
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//这里若不加此判断,则每次点击未修改成功的按钮后,页面都会重传,然后恢复一开始的值,不会保存修改的值
if (!IsPostBack)
{
Owner owner = new BLayer().GetAnAccountBydIndex_TO_Owner(Convert.ToInt32(Application["Index"]));
(Master.FindControl("textBox_Name") as TextBox).Text = owner.Name;
if (owner.Sex == '男')
(Master.FindControl("radioBtn_Boy") as RadioButton).Checked = true;
if (owner.Sex == '女')
(Master.FindControl("radioBtn_Girl") as RadioButton).Checked = true;
(Master.FindControl("textBox_Phone") as TextBox).Text = owner.Phone;
(Master.FindControl("textBox_BuildNum") as TextBox).Text = owner.BuildNum;
(Master.FindControl("textBox_Unit") as TextBox).Text = owner.Unit;
(Master.FindControl("textBox_RoomNum") as TextBox).Text = owner.RoomNum;
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
char sex = '男';
if ((Master.FindControl("radioBtn_Girl") as RadioButton).Checked)
sex = '女';
Owner owner = new Owner();
owner.Oid = Convert.ToInt32(Application["index"]);
owner.Name = (Master.FindControl("textBox_Name") as TextBox).Text.ToString();
owner.Sex = sex;
owner.Phone = (Master.FindControl("textBox_Phone") as TextBox).Text.ToString();
owner.BuildNum = (Master.FindControl("textBox_BuildNum") as TextBox).Text.ToString();
owner.Unit = (Master.FindControl("textBox_Unit") as TextBox).Text.ToString();
owner.RoomNum = (Master.FindControl("textBox_RoomNum") as TextBox).Text.ToString();
string message = new BLayer().UpdateAnAccount(owner);
BLayer.MessageBox(IntPtr.Zero, message, "提示!", 0);
}
}
}
运行,测试功能,没问题。
分割线二
到这里已经实现实现了实体类。
2019年5月22日23:39:08