ASP.Net MVC OA项目笔记<六>
1.1.1 开始写业务,先写业务的实现再写业务的接口
业务类中也是有写增删改查公用的方法
引用Model,IDAL,DALFactory
BLL添加两个类 UserInfoService,BaseService,并让UserInfoService继承BaseService


1.2.1 业务层要调用DBSession,所以要把DBSession给new出来
每一个业务子类都要通过DBSession来调用具体的数据操作类,如果把DBSession创建在每个业务子类中就存在重复性了,所以放在基类里面

1.2.2 完成了业务成调DBSession后,把业务层的增删改查方法也放的业务的基类里面
试着把IBaseDal的过滤查询方法复制过来
用CurrentDBSession调用数据

1.CurrentDBSession :创建DBSession对象
2.UserInfoDal:DBSession类中通过反射创建实例

3.LoadEntities:UserInfoDal实例继承=>IUserInfoDal接口,但是IUserInfoDal接口继承=>IBaseDal接口
所以UserInfoDal可以调用IBaseDal接口中的方法


1.2.3 但是BaseService是个基类,根本不知道要通过DBSession操作那个数据的实例,不能直接调用UserInfoDal,子类才可以这样调,所以不能这样写
1.可以把父类改成抽象类

2.加一个抽象方法

3.然后定义一个构造方法,在构造方法中把抽象方法调一次
因为子类继承父类,也会继承父类的构造方法,所以子类在创建对象时,就会先调用一次这个构造方法,执行里面的抽象方法

3.然后定义一个公共属性

1.2.4 实现子类的抽象类

1.CurrentDal:公共属性,类型是IBaseDal,子类可以拿到父类的CurrentDal,拿到父类DBSession属性的实例
2.this:子类
3.CurrntDBsession:在父类定义的,可以拿到父类的DBSession属性
4..UserInfoDal:调该子类(UserInfoService)的数据操作实例(UserInfoDal),UserInfoDal实现了自己的接口IUserInfoDal,IUserInfoDal又继承了IBaseDal
1.2.5 多态
父类中不知道通过DBSession获取哪个子类的实例,但是子类知道
UserInfoService通过DBSession获取的肯定是UserInfoDal
所以把这个业务基类BaseService改成抽象类 ,加一个抽象方法,并且把这个抽象方法放在基类的构造方法里面,让他创建时调用一次
而且表现层调用业务类,表现层把这个业务类一new的话,它继承的构造方法就会就会执行,构造方法一执行,就执行子类的抽象方法
表现层=>new UserInfoService=>执行父类构造方法=>执行子类抽象方法SetCurrentDal( )=>拿到子类的数据实例UserInfoDal赋值给公共属性CurrentDal
这时候就可以通过CurrentDal.LoadEntities( )拿到UserInfo的查询数据了

1.2.6 代码
//在基类中完成DBSession的调用,然后将业务层中公共的方法定义在基类中,但这些方法不知道通过DBSession来获取哪个数据操作类的实例。
//所以将该业务基类定义成抽象类,加上一个抽象方法,加上一个IBaseDal属性,并让基类的构造方法调用抽象方法目的是在表现层new具体的
//业务子类,父类的构造方法被调用,这时执行抽象方法,但是执行的是子类中具体的实现。业务子类知道通过DBSession获取哪个数据操作类的实例。
public abstract class BaseService<T> where T : class, new()
{
public IDBSession CurrentDBSession
{
get
{
return new DBSession();//暂时这么写
}
}
public IBaseDal<T> CurrentDal { get; set; }//公共属性
public abstract void SetCurrentDal();//抽象方法
public BaseService()//构造函数
{
SetCurrentDal();//子类一定要实现抽象方法
} public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda)
{
return CurrentDal.LoadEntities(whereLambda);
}
}
public class UserInfoService : BaseService<UserInfo>
{
public override void SetCurrentDal()
{
CurrentDal = this.CurrentDBSession.UserInfoDal;
}
}
1.3.1 表现层加控制器,调试一下
1.表现层加个控制器,叫UserInfoControl
2.右键=>添加=>控制器




1.4.1给WebApp引入BLL和Model
1.4.2 表现层调业务层的查询方法



1.当用户在地址栏里面输了UserInfo这个控制器的Index方法时,先new,子类的构造方法先执行=>父类的构造方法肯定执行=>
一执行调它的抽象方法SetCurrentDal()=>一调抽象方法先调子类的抽象方法=>执行子类的抽象方法=>子类可以拿到父类的DBSession属性=>
通过它调UserInfoDal=>把UserInfoDal的实例拿给父类的CurrentDal(在父类定义)=>为什么把CurrentDal类型赋为IBaseDal=>
因为所有的数据操作类都实现了自己的接口,并且每一个接口都继承了IBaseDal=>这个流程走完了,就表示这个bll对象被new出来了=>
接着走Index()方法=>调父类业务层的方法LoadEntities=>CurrentDal有值(UserInfoDal)=>调UserInfoDal中的LoadEntities(查询方法)
1.5.1 把业务层的基类都封装好(其他增删改查方法都补上)
//在基类中完成DBSession的调用,然后将业务层中公共的方法定义在基类中,但这些方法不知道通过DBSession来获取哪个数据操作类的实例。
//所以将该业务基类定义成抽象类,加上一个抽象方法,加上一个IBaseDal属性,并让基类的构造方法调用抽象方法目的是在表现层new具体的
//业务子类,父类的构造方法被调用,这时执行抽象方法,但是执行的是子类中具体的实现。业务子类知道通过DBSession获取哪个数据操作类的实例。
public abstract class BaseService<T> where T : class, new()
{
public IDBSession CurrentDBSession
{
get
{
return new DBSession();//暂时这么写
}
}
public IBaseDal<T> CurrentDal { get; set; }//公共属性
public abstract void SetCurrentDal();//抽象方法
public BaseService()//构造函数
{
SetCurrentDal();//子类一定要实现抽象方法
} //查询过滤
public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda)
{
return CurrentDal.LoadEntities(whereLambda);
}
//分页
public IQueryable<T> PageLoadEntities<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderbyLambda, bool isAsc)
{
return CurrentDal.PageLoadEntities<s>(pageIndex, pageSize, out totalCount, whereLambda, orderbyLambda, isAsc);
}
//新增
public T AddEntity(T entity)
{
CurrentDal.AddEntity(entity);
CurrentDBSession.SaveChanges();//保存
return entity; }
//删除
public bool DeleteEntity(T entity)
{
CurrentDal.DeleteEntity(entity);
return CurrentDBSession.SaveChanges();
}
//编辑
public bool EditEntity(T entity)
{
CurrentDal.EditEntity(entity);
return CurrentDBSession.SaveChanges();
}
}
1.6.1 表现层调业务层也是调接口,这一段改成接口的类型,所以需要给它新增接口

1.6.2 新增接口 IUserInfoService,IBaseService
IBLL引用Model,IDAL
让IUserInfoService继承IBaseService
public interface IBaseService<T> where T : class, new()
{
IDBSession CurrentDBSession { get; }
IBaseDal<T> CurrentDal { get; set; }
IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda);
IQueryable<T> PageLoadEntities<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderbyLambda, bool isAsc);
T AddEntity(T entity);
bool DeleteEntity(T entity);
bool EditEntity(T entity); }
public interface IUserInfoService:IBaseService<UserInfo>
{ }
1.7.1 业务层BLL引用IBLL
具体业务类UserInfoService 要继承IUserInfoService
public class UserInfoService : BaseService<UserInfo>,IUserInfoService
{
public override void SetCurrentDal()
{
CurrentDal = this.CurrentDBSession.UserInfoDal;
}
}
1.8.1 WebApp引入IBLL
这里bll改成接口类型, 重新生成下解决方案

public class UserInfoController : Controller
{
// GET: UserInfo
IBLL.IUserInfoService bll = new BLL.UserInfoService();
public ActionResult Index()
{
//表现层调业务层的查询方法,里面放一个lambda表达式
bll.LoadEntities(c=>c.ID==);
return View();
}
}
1.8.2 如果要添加

1.8.3 如果是非常复杂的业务,就要再IUserInfoService中再写一个新的复杂的方法,表现层调用这个复杂的方法运算
CurrentDBSession 要保证线程的唯一, 这样用的就是同一个DBSession,所以其实只new了一次

1.8.4 CurrentDBSession线程的唯一
给DALFactory添加一个类DBSessionFactory
public class DBSessionFactory
{
public static IDBSession CreateDBSession()
{
IDBSession DbSession = (IDBSession)CallContext.GetData("dbSession");
if(DbSession==null)
{
DbSession = new DBSession();
CallContext.SetData("dbSession", DbSession);
}
return DbSession;
}
}
1.8.5 把BaseService 中获取DBSession的方法改了

//在基类中完成DBSession的调用,然后将业务层中公共的方法定义在基类中,但这些方法不知道通过DBSession来获取哪个数据操作类的实例。
//所以将该业务基类定义成抽象类,加上一个抽象方法,加上一个IBaseDal属性,并让基类的构造方法调用抽象方法目的是在表现层new具体的
//业务子类,父类的构造方法被调用,这时执行抽象方法,但是执行的是子类中具体的实现。业务子类知道通过DBSession获取哪个数据操作类的实例。
public abstract class BaseService<T> where T : class, new()
{
public IDBSession CurrentDBSession
{
get
{
//return new DBSession();//暂时这么写
return DBSessionFactory.CreateDBSession();
}
}
public IBaseDal<T> CurrentDal { get; set; }//公共属性
public abstract void SetCurrentDal();//抽象方法
public BaseService()//构造函数
{
SetCurrentDal();//子类一定要实现抽象方法
} //查询过滤
public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda)
{
return CurrentDal.LoadEntities(whereLambda);
}
//分页
public IQueryable<T> PageLoadEntities<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderbyLambda, bool isAsc)
{
return CurrentDal.PageLoadEntities<s>(pageIndex, pageSize, out totalCount, whereLambda, orderbyLambda, isAsc);
}
//新增
public T AddEntity(T entity)
{
CurrentDal.AddEntity(entity);
CurrentDBSession.SaveChanges();//保存
return entity; }
//删除
public bool DeleteEntity(T entity)
{
CurrentDal.DeleteEntity(entity);
return CurrentDBSession.SaveChanges();
}
//编辑
public bool EditEntity(T entity)
{
CurrentDal.EditEntity(entity);
return CurrentDBSession.SaveChanges();
}
}
ASP.Net MVC OA项目笔记<六>的更多相关文章
- ASP.Net MVC OA项目笔记<五>
1.1.1 抽象工厂封装数据操作类实例创建,然后DBSession调用抽象工厂,修改DBSession CZBK.ItcastOA.DALFactory数据会话层调数据层不能直接new,要封装一下解 ...
- ASP.Net MVC OA项目笔记<二>
1.1.0 创建数据层 1.1.1 CZBK.ItcastOA.IDAL 引用 CZBK.ItcastOA.Model 1.2.1 给IDAL添加一个接口IUserInfoDal 里面写增删改查分页的 ...
- ASP.Net MVC OA项目笔记<四>
1.1.1 EF线程唯一 在数据层中用到了EF的实例,在数据会话层也用到了,所以在一个请求中只能创建一个EF实例(线程内唯一对象),把它封装成工厂类 1.1.2 为了防止相互引用,循环引用,所以这个工 ...
- ASP.Net MVC OA项目笔记<三>
1.1.1 业务层和数据层之间加一个数据会话层,封装所有数据操作类实例的创建(工厂类) 工厂类是负责对象的创建 作用:将BLL和DAL解耦了,提供一个数据访问的统一访问点 数据会话层DBSession ...
- ASP.Net MVC OA项目笔记<一>
1.1.1 新建空白解决方案CZBK.ItcastOA 1.2.1 添加类库 1.2.2 同上添加多个类库 生成的 class1.cs先不用删除,删了的后,后面可能没办法直接点引用 1.3.1 添加表 ...
- ASP.NET MVC企业级项目框架
ASP.NET MVC企业级项目框架 MVC项目搭建笔记---- 项目框架采用ASP.NET MVC+Entity Framwork+Spring.Net等技术搭建,搭建过程内容比较多,结合了抽象工厂 ...
- 使用Visual Studio 2015 开发ASP.NET MVC 5 项目部署到Mono/Jexus
最新的Mono 4.4已经支持运行asp.net mvc5项目,有的同学听了这句话就兴高采烈的拿起Visual Studio 2015创建了一个mvc 5的项目,然后部署到Mono上,浏览下发现一堆错 ...
- ASP.NET MVC搭建项目后台UI框架—1、后台主框架
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—11、自动加载下拉框查询
ASP.NET MVC搭建项目后台UI框架—1.后台主框架 需求:在查询记录的时候,输入第一个字,就自动把以这个字开头的相关记录查找出来,输入2个字就过滤以这两个子开头的记录,依次类推. 突然要用到这 ...
随机推荐
- 2017/2/24:Maven的pom jar war的区别
首先,Run ——> Edit Configurations,这时候如下图: 然后点击左上角的加号,可以添加一个新的配置,如下图: 选择Maven,如下图: 下面填上自己的配置信息,点击appl ...
- JS高级- OOP-ES5
1. OOP 面向对象三大特点: 封装,继承,多态 封装: 问题: 构造函数可重用代码和结构定义,但无法节约内存 为什么: 放在构造函数内的方法定义,每new一次,都会反复创建副本——浪费内存 解决: ...
- keras框架的MLP手写数字识别MNIST,梳理?
keras框架的MLP手写数字识别MNIST 代码: # coding: utf-8 # In[1]: import numpy as np import pandas as pd from kera ...
- 再读c++primer plus 006
使用类: 1.重载限制:(1)重载后的运算符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载运算符 (2)使用运算符时不能违反运算符原来的语法规则,不能修改运算符的优先级 (3)不能创 ...
- AOP的异常通知
一.配置异常通知的步骤 (Aspectj方式) 1.只有当切点报异常才能触发异常通知 2.在spring中有Aspectj 方式提供了异常通知方法 2.1 如果希望通过 schema-base 实 ...
- 2018.11.01 NOIP训练 梭哈(模拟)
传送门 这题貌似不考智商啊. 直接按题意写就可以了. 事实上把牌从小到大排序之后写起来很舒服的. 然后就是有些地方可以人脑减代码量和判断次数. (提示:满堂红和某几种同类型的牌的大小判断) 然后注意A ...
- 牛客训练五:炫酷路途(c++与dp)
题目链接:传送门 思路:每隔2^i(0<=i<=INF)就有一条路径,所以可以将从头到尾的路线视为一个有向图, 将ai,bi以此输入,然后将路径从小到大排序,不断更新路径. __built ...
- JSAAS 平台实现 微信类似的TOKEN机制
在企业微信中,我们在调用微信接口时,我们需要首先获取token,然后根据token,调用API接口方法.这个token是有生命周期的,微信的token默认的生命周期是7200秒. 因此这个token可 ...
- ubuntu卸载软件命令,apt-get remove
第一步,apt-get remove xxx :就是卸载xxx 或者 apt-get remove --purge xxx :卸载xxx并清除配置. 这两条命令对于依赖则是不管的.因为别的软件可 ...
- sql计算经纬度得出最近距离的公式
sql计算经纬度得出最近距离的公式 //根据经纬度计算两点距离 mappoint //数据库已有字段,商家经纬度 实例:113.272148,23.147299 $lon = "" ...