宏观:要明确是如何从三层转七层
引用图片自:图片作者原文章
实体层(entity)
:用来封装一些功能性代码,定义实体类型和实体集合,用来各层次传递参数用来存放用户输入的信息。用getset实现达到传递参数的方法达到可以可读可写,同时又有封装性。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Entity { public class UserInfo { //定义用户ID字段 private int userid; public int UserId { get { return userid; } set { userid = value; } } //定义用户名 private string username; public string UserName { get { return username; } set { username = value; } } //定义密码字段 private string password; public string PassWord { get { return password;} set { password = value; } } } }
接口层(IDAL)
:定义一个统一的接口方法selectuser,解除B层和D层的耦合,具体代码靠DAL
实现。
注意:因为返回值类型为DataTable ,所以应该引用数据的命名空间。
using System.Data;
Data是数据的意思。
顾名思义,引用这个dll即表示你的命名空间下有需要使用数据、数组的地方,可以直接使用数组类型,而不需要再添加前缀。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; namespace IDAL { public interface LoginIDAL { DataTable selectUser(Entity.UserInfo userInfo); } }
数据访问层(DAL)
:提供基本的数据访问,该层将有关数据库的操作放在单独的一个类中,针对数据的增删改查。
DAL层会封装一个sqlHelper。目的是连接数据库实现对数据库的增删改查,这是为了服务于DAL层的。
首先有个构造函数连接上数据库,然后重载了对数据库的增删改查有无参数的方法,
LoginSqlHelper
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data.SqlClient; using System.Data; using System.Configuration; namespace DAL { ///<summary> ///SqlHhelper created by ZGY 2021年11月22日20:25:30 ///</summary> public class SqlHelper { private SqlConnection Conn = null; private SqlCommand Cmd = null; private SqlDataReader SqlSdr = null; public SqlHelper() { //利用反射连接数据库 //除了要在上边添加命名空间,也要手动在类的引用里边添加引用才能生效 //这里的AppSetting要注意大小写 string strconn = ConfigurationManager.AppSettings["strConn"]; //实例化一个连接 Conn = new SqlConnection(strconn); } ///<summary> ///打开数据库 ///<summary/> /// <returns>sqlConnection</returns> private SqlConnection GetConn() { if (Conn.State != ConnectionState.Open) { try { Conn.Open(); } catch (Exception ex) { Conn.Dispose();//没有成功打开,释放资源 throw new Exception("打开数据库失败!"); } } return Conn; } ///<summary> ///执行不带参数的增删改操作 ///<summary/> ///<param name="CmdText">执行的sql语句或者存储过程</param> ///<param name="CmdType">语句类型</param> /// /// <returns>sqlConnection</returns> public int ExecuteNonQuery(string CmdText, CommandType CmdType) { //数据库连接语句 int res; try { Cmd = new SqlCommand(CmdText, GetConn()); Cmd.CommandType = CmdType; res = Cmd.ExecuteNonQuery(); } catch (Exception ex) { throw ex; } finally { if (Conn.State == ConnectionState.Open) { Conn.Close(); } } return res; } /// <summary> /// 执行带参数的增删改操作 /// </summary> /// <param name="CmdText">执行的SQL语句或存储过程</param> /// <param name="parameters">参数</param> /// <param name="CmdType">(SQL语句或存储过程)的类型</param> /// <returns>返回增删改的操作数(受影响的行数)</returns> public int ExecuteNonQuery(string CmdText, SqlParameter[] parameters,CommandType CmdType) { int res; try { Cmd = new SqlCommand(CmdText, GetConn()); //先建立sql语句 Cmd.Parameters.AddRange(parameters); //再进行参数匹配 Cmd.CommandType = CmdType; res = Cmd.ExecuteNonQuery(); } catch (Exception ex) { throw ex; } finally { if (Conn.State==ConnectionState.Open) { Conn.Close(); } } return res; } /// <summary> /// 执行不带参数的查询操作 /// </summary> /// <param name="CmdText">执行的SQL语句或存储过程</param> /// <param name="CmdType">(SQL语句或存储过程)类型</param> /// <returns>查询后的数据</returns> public DataTable ExecuteQuery(string CmdText, CommandType CmdType) { DataTable dt = new DataTable(); using (SqlSdr = Cmd.ExecuteReader(CommandBehavior.CloseConnection)) { Cmd = new SqlCommand(CmdText, GetConn()); Cmd.CommandType = CmdType; dt.Load(SqlSdr); } return dt; } /// <summary> /// 执行带参数的查询 /// </summary> /// <param name="CmdText">执行的SQL语句或存储过程</param> /// <param name="parameters">(SQL语句或存储过程)类型</param> /// <param name="CmdType"></param> /// <returns>查询后的数据</returns> public DataTable ExecuteQuery(string CmdText, SqlParameter[] parameters, CommandType CmdType) { DataTable dt = new DataTable(); Cmd = new SqlCommand(CmdText, GetConn()); Cmd.CommandType = CmdType; Cmd.Parameters.AddRange(parameters); using (SqlSdr = Cmd.ExecuteReader(CommandBehavior.CloseConnection)) { dt.Load(SqlSdr); } return dt; //DataTable dt = new DataTable(); //using (SqlSdr = Cmd.ExecuteReader(CommandBehavior.CloseConnection)) //{ // Cmd = new SqlCommand(CmdText, GetConn()); // Cmd.Parameters.AddRange(parameters); // Cmd.CommandType = CmdType; // dt.Load(SqlSdr); //} //return dt; } } }
LoginDAL
这里的代码和配置文件息息相关,容易出现错误,容易出现的错误和解决办法都会放在文章最后奥。
DAL是为了实现IDAL层中的方法。对数据进行增删改查。
首先实例化一个sqlhelper,对数据库进行连接
然后声明一个sql参数的数组,将实体层中的参数值传给我们定义的参数中
然后再数据库中进行语句查询。
然后大家都返回到sqlhelper中的一个带参数查询的方法。