asp.net 建多个项目实现三层的实例——读取一张表中的记录条数
学习asp.net两周,通过学习发现,.net和php之间的区别还是蛮大的,比php要复杂一些,开始学习的有些吃力,后来跟着传智播客里的老师学习,渐渐的学到了一些东西。
今天要记录一下.net里的简单的三层架构是如何实现的,希望通过一次次的博客记录能加深自己对知识点的理解和记忆,当然,如果有幸能帮到某些和我一样的同学,那也是非常荣幸和欣喜的,好了,闲言少叙,下面开始记录。
三层架构我自己也不是很熟,只是大概的知道其工作原理,以及构建流程,这里贴出传智博客的老师讲解的一张原理图,然后就略过了,毕竟本人太菜,不敢误导别人。

如上图所示,是一张三层结构工作原理图,三层结构分为
UI(视图层):人眼直接能看到的内容,如winform,website等;
Bll(业务逻辑层):处理与业务相关的逻辑;
Dal(数据访问层):只负责接收业务逻辑层的调用,处理相关的数据库CURD操作,只跟数据库打交道,与UI层完全分离;
Common和Model:一些三层之外的文件,这些文件可以写一些静态类,实体类等东西,这里面的内容三个类都可以调用;
关于三层结构的原理只做简单说明,想要详细了解的同学,请自行百度,阅读技术大牛们的博客,下面对该三层实现的步骤做详尽的说明。
第一步:创建UI,BLL,和DAL
1.打开ide ,VS20XX,(我这里用的是最新版的VS2017),点击文件 ==》 新建 ==》项目,如下图所示:

2.选择其他项目类型下的VS'解决方案 ==》空白解决方案,命名,选择保存路径后点击确定;


3.右击解决方案 ==》点击添加 ==》新建项目 ==》选择 Windows窗体应用 ==》命名为UI(这里我们以窗体作为显示层,这里也可以把website空网站作为显示层,用起来都是一样的);

4.右击解决方案,添加新项目 ==》选择新建 类库(.net Framework),这里不要选错,因为选项里有三个类库选项,我们应该选择 后面 括号里带 .net Framework 的类库,选其他的会出错,至于为什么,我也不知道,见谅见谅哈。

5.同样的方法,新建Bll,建好之后,应该有如图所示的几个东西,

第二步:所要完成的功能的说明:
在这里我要完成的功能其实非常非常的简单,就是查询一张表,看里面有多少条数据,然后返回数据的条数,大致是这样的,我们有一个窗体窗体上有个按键,点击这个按键(查看XXX表中的数据条数),弹出窗口,显示:XXX表中有XX条数据。
这里我要操作的是一个名为TbAreas的表,如图所示:

第三步:三层实现流程介绍
1.确定sql语句
为了保证数据库操作语句不出错误,我先在数据库中新建查询,看能不能查到我要的结果,我用的数据库是sqlserver,数据库管理软件是微软的 MSMS,查询结果如图所示:

如图所示可以看到,用该语句查询出的结果是表中有54条数据,下面我看一下是否有误:

由图可知,无误,故我们的语句确定为:sql = "select count(*) from TbAreas" ;
2.在数据访问层编写执行该sql语句的函数
首先给DAL里的Class1.cs重命名为:表名+Dal+.cs,这里饿哦们命名为:TbAreasDal.cs;
需要我知道的是,三层里,每个表对应一个类,以后操作同一张表的所有函数都写在同一个类中。
然后,开始编写代码了,在Dal里的TbAreasDal类中编写如下方法:
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Dal
{
public class TbAreasDal
{
//在这里编写数据库操作函数
public int GetRecordCount()
{
//sql语句
string sql = "select count(*) from TbAreas";
//调用SqlHelper里的方法执行查操作语句
return (int)SqlHelper.ExcuteScalar(sql,System.Data.CommandType.Text);
}
}
}
这个里面的代码就是这样了,但是,很遗憾,这个代码是错误的,贴上图片给你看:

因为我的代码里没有SqlHelper这个类。SqlHelper这个类是需要自己封装的一个数据库操作类,这个类怎么封装不是我今天要记录的内容,以后有时间会记录一下的。这个类我已经封装过,直接复制到Dal项目下,如下图所示:
先给代码:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 封装SqlHelper类
{
public class SqlHelper
{
//定义一个连接字符串
//readonly修饰的变量,只能在初始化的时候赋值,以及构造函数中赋值
private static readonly string conStr = ConfigurationManager.ConnectionStrings["mssqlserver"].ConnectionString; //1.执行增(insert)删(delete)改(update)的方法 ExecuteNonQuery()
public static int ExecuteNonQurey(string sql,CommandType cmdType,params SqlParameter[] pms)
{
using (SqlConnection con = new SqlConnection(conStr))
{
using (SqlCommand cmd = new SqlCommand(sql,con))
{
cmd.CommandType = cmdType;
if (pms != null)
{
cmd.Parameters.AddRange(pms);
}
con.Open();
return cmd.ExecuteNonQuery();
}
}
} //2.执行查询,返回单个值的方法 ExecuteScalar
public static object ExecuteScalar(string sql, CommandType cmdType, params SqlParameter[] pms)
{
using (SqlConnection con = new SqlConnection(conStr))
{
using (SqlCommand cmd = new SqlCommand(sql, con))
{
cmd.CommandType = cmdType;
if (pms != null)
{
cmd.Parameters.AddRange(pms);
}
con.Open();
return cmd.ExecuteScalar();
}
}
} //3.执行查询,返回多行的方法ExecuteReader
public static SqlDataReader ExecuteReader(string sql, CommandType cmdType, params SqlParameter[] pms)
{
SqlConnection con = new SqlConnection(conStr);
using (SqlCommand cmd = new SqlCommand(sql,con))
{
cmd.CommandType = cmdType;
if(pms != null)
{
cmd.Parameters.AddRange(pms);
}
try
{
if (con.State == ConnectionState.Closed)
{
con.Open();
} //System.Data.CommandBehavior.CloseConnection这个枚举参数,表示将来使用完毕SqlDataReader后,在关闭reader的同时,在SqlDataReader内部会将关联的Connection对象也关闭掉
return cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
}
catch
{
con.Close();
con.Dispose();
throw;
}
} } public static DataTable ExecuteDataTable(string sql,CommandType cmdType,params SqlParameter[] pms)
{
DataTable dt = new DataTable();
using (SqlDataAdapter adapter = new SqlDataAdapter(sql,conStr))
{
adapter.SelectCommand.CommandType = cmdType;
if (pms != null)
{
adapter.SelectCommand.Parameters.AddRange(pms);
}
adapter.Fill(dt); }
return dt;
}
}
}
然后看看图片:

细心的你一定一眼就看到了这里有个bug啦,当前文中不存在这个ConfigurationManager类,所以啊,我要把这个东西搞进来先。那么问题来了,在哪里搞呢,自己写一个吗,不,不是的,这是个系统自带的东西,我只需要引用进来就行了;
怎么引用,往下看:
(1)右击Dal下的引用,点击 添加引用 ==》程序集 ==》 框架(如果最近引用过可以点击最近)==》找到这个东西 System.Configuration, 打上沟,点击确定,就可以了

(2)看一下引用后的结果吧:

现在可以看到,那个错误没有了。
事实上,做到这一步,我们的这个SqlHelper还是不能正常使用的,为什么,细心的你可能会发现,在SqlHelper里链接数据库的字符串conStr后面的东西跟我们学的时候看到的语句不一样啊,这里既没写我要连那个服务器,也没写要连那个数据库,更没写是那个用户登录的,登录密码是啥?那咋办呢,这是为啥呢?
下面来讲:因为数据库的链接是一个很频繁的操作,如果我们在每个数据库连接的方法中都写上一串下面这个代码:
string conStr = "Data Source = .;Initial Catalog = 数据库名;User ID = sa;Password = XXXX";
那会是非常繁琐的,而且如果有朝一日需要改动这个数据库,那需要改的文件就太多了,因此啊,我们把这个东西放到了一个全局配置文件中,这个文件就是App.config,这个文件vs2017是默认就有的,以前版本的好像要自己新建。
下面点击打开App.config, 在里面添加<connectionStrings><add XXXXXXXX/></connectionStrings>这样的一串代码:
代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name="mssqlserver" connectionString="Data Source = acer-pc;Initial Catalog = FirstDB;User ID = sa; Password = 168168"/>
</connectionStrings>
</configuration>
添加好后,把name = "XXX"里的这个XXX名字写到SqlHelper里的那个位置去就可以了
到这个地方这数据库相关的东西就弄好了,下面我们回到TbAreasDal.cs里来,

此时SqlHeiper这个类已经有了,但是还没有引进来。
怎么引,简单,将光标定位到划红线的地方,使用快捷键 Ctrl + Alt +F10 ,会弹出提示语句,选中提示语句就可以了,这个快捷键还蛮好用,可以记一记。如图所示:

下面给出正确的TbAreasDal.cs代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 封装SqlHelper类; namespace Dal
{
public class TbAreasDal
{
//在这里编写数据库操作函数
public int GetRecordCount()
{
//sql语句
string sql = "select count(*) from TbAreas";
//调用SqlHelper里的方法执行查操作语句
return (int)SqlHelper.ExecuteScalar(sql,System.Data.CommandType.Text);
}
}
}
到这里Dal层就写完了,下面来看Blll层。
3.在业务层编写业务逻辑代码
首先给Bll里的类重命名为TbAreasBll.cs,然后编写代码:
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Bll
{
public class TbAreasBll
{
TbAreasDal dal = new TbAreasDal();
public int GetRecordCount()
{
return dal.GetRecordCount();
}
}
}
但是,此时这个代码还有问题,如下图所示

没错,这里缺少Dal项目的引用啊,只有把他引进来,才能使用他啊。怎么引,两种办法,一种、直接在上图左边的红框上点一下,还有一种,右击Bllx下的引用 ==》添加引用 ==》 项目 ==》勾上Dal,如图所示:

就是这样子了,引进来后就没有错误了。咋的,不信啊,不信给你看图啊:

到这里,业务层也交代完了,接下来看UI层。
4.UI层——进行用户操作,获取反馈结果
首先给UI层的窗体重命名为AreasNum.cs,然后在上面添加一个按钮。,如下图所示:

这样就可以了,接下来双击按钮,进行相应的代码编辑:代码如下:
private void button1_Click(object sender, EventArgs e)
{
//实例化TbAreasBll类,这里同样要引用一下Bll这个命名空间,否则会报错
TbAreasBll bll = new TbAreasBll(); //调用bll里的方法,获取条数
int row = bll.GetRecordCount(); //显示条数
MessageBox.Show("TbAreas表中有"+ row + "条记录"); }
需要注意的是,这个代码里同样需要先引用Bll,不然同样会出错,程序运行的结果为:

这与我前面用sql语句在数据库直接查询的数据是一致的。
好了,这个最简单的三层就记录到这里啦,虽然是如此的简单,但还是写了这么长,没办法,谁叫我菜呢。
以上的内容是观看传智播客赵晓虎老师的视频课所学,在此感谢传智播客。对于以上所述内容,发现有重大谬误的,欢迎口水留言,谢谢!
我的QQ:3074596466
asp.net 建多个项目实现三层的实例——读取一张表中的记录条数的更多相关文章
- asp显示记录条数
Sql = "select * from xin126 where ID=" & id Rs.Open Sql,Conn,1,1 %> 共有<strong st ...
- 20.采集项目流程篇之清洗数据绑定到hive表中
先启动hive 在mydb2这个数据库中创建表: create external table mydb2.access(ip string,day string,url string,upflow s ...
- 《项目经验》--通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来的Json数据写入数据库表中
先看一下我要实现的功能界面: 这个界面的功能在图中已有展现,课程分配(教师教授哪门课程)在之前的页面中已做好.这个页面主要实现的是授课,即给老师教授的课程分配学生.此页面实现功能的步骤已在页面 ...
- 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程
反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) 背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...
- Web项目的三层架构和MVC架构异同
http://www.cnblogs.com/zhhh/archive/2011/06/10/2077519.html 又看到有人在问三层架构和MVC的关系,感觉这种问题有点教条化了.因为它们都在逻辑 ...
- 【.NET特供-第三季】ASP.NET MVC系列:MVC与三层图形对照
近期在开发小组在研究:BS项目中是利用'MVC框架'还是继续沿用'三层'的问题. 由于曾经的.NET项目大多数都是利用三层开发的,所以大多数人都可以对三层进行熟练地运用.而项目的開始我们也曾听说过MV ...
- Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架
Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...
- 《ASP.NET Core应用开发入门教程》与《ASP.NET Core 应用开发项目实战》正式出版
“全书之写印,实系初稿.有时公私琐务猬集,每写一句,三搁其笔:有时兴会淋漓,走笔疾书,絮絮不休:有时意趣萧索,执笔木坐,草草而止.每写一段,自助覆阅,辄摇其首,觉有大不妥者,即贴补重书,故剪刀浆糊乃不 ...
- # asp.net core 1.0 项目结构
1.环境 开发:VS2015 平台:window 7 2.解决方案级别结构 创建一个ASP.NET 5 Template Empty项目: src:存放项目(projects) global.json ...
随机推荐
- 做个流量站-聚茶吧, 汇聚"茶"的地方
犹豫了好久,终于下定决心,做一回个人站长了,虽然没啥经验,但毕竟也是IT科班出身了,准备用一年的事件摸索一下内容站和SEO,看看能否积累点经验,赚点小钱. 推酷-靠爬虫起家的内容站 做内容站,站长们都 ...
- 样式布局与 BFC
一.几类视图 内联视图:inline 单行 块级视图:block 换行,有高度 行内块级视图:inline-block 单行,有高度 二.几类布局 块级布局 换行,通过设置 margin 水平居中 & ...
- XSS之偷梁换柱--盲打垃圾短信平台
https://www.t00ls.net/thread-49742-1-1.html
- git常用方法整理
Git是什么? Git是目前世界上最先进的分布式版本控制系统(没有之一). Git有什么特点?简单来说就是:高端大气上档次! 初始化本地仓库 mkdir xxx cd xxx git init 创建本 ...
- OJ001
#include<stdio.h> int main(){ int a,b; while (scanf("%d%d",&a,&b)!=EOF){ pri ...
- DOS命令(一)
1. echo 输出内容,用来输出文字. [例如:echo hello] 2. titile 标题,用来修改标题. 3. color 背景色前景色,用来设置背景色和前景色 0 = 黑色 8 = 灰色 ...
- dijkstra算法解决单源最短路问题
简介 最近这段时间刚好做了最短路问题的算法报告,因此对dijkstra算法也有了更深的理解,下面和大家分享一下我的学习过程. 前言 呃呃呃,听起来也没那么难,其实,真的没那么难,只要弄清楚思路就很容易 ...
- AI-2.梯度下降算法
上节定义了神经网络中几个重要的常见的函数,最后提到的损失函数的目的就是求得一组合适的w.b 先看下损失函数的曲线图,如下 即目的就是求得最低点对应的一组w.b,而本节要讲的梯度下降算法就是会一步一步地 ...
- Java笔试题:给定一个ReadOnlyClass的对象roc,能否把这个对象的age值改成30?
在Java笔试面试中,经常会遇到代码题,今天我们就来看一则Java代码笔试题. 有如下代码: Class ReadOnlyClass { private Integer age=20; public ...
- [Swift]LeetCode306. 累加数 | Additive Number
Additive number is a string whose digits can form additive sequence. A valid additive sequence shoul ...