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项目笔记<六>的更多相关文章

  1. ASP.Net MVC OA项目笔记<五>

    1.1.1  抽象工厂封装数据操作类实例创建,然后DBSession调用抽象工厂,修改DBSession CZBK.ItcastOA.DALFactory数据会话层调数据层不能直接new,要封装一下解 ...

  2. ASP.Net MVC OA项目笔记<二>

    1.1.0 创建数据层 1.1.1 CZBK.ItcastOA.IDAL 引用 CZBK.ItcastOA.Model 1.2.1 给IDAL添加一个接口IUserInfoDal 里面写增删改查分页的 ...

  3. ASP.Net MVC OA项目笔记<四>

    1.1.1 EF线程唯一 在数据层中用到了EF的实例,在数据会话层也用到了,所以在一个请求中只能创建一个EF实例(线程内唯一对象),把它封装成工厂类 1.1.2 为了防止相互引用,循环引用,所以这个工 ...

  4. ASP.Net MVC OA项目笔记<三>

    1.1.1 业务层和数据层之间加一个数据会话层,封装所有数据操作类实例的创建(工厂类) 工厂类是负责对象的创建 作用:将BLL和DAL解耦了,提供一个数据访问的统一访问点 数据会话层DBSession ...

  5. ASP.Net MVC OA项目笔记<一>

    1.1.1 新建空白解决方案CZBK.ItcastOA 1.2.1 添加类库 1.2.2 同上添加多个类库 生成的 class1.cs先不用删除,删了的后,后面可能没办法直接点引用 1.3.1 添加表 ...

  6. ASP.NET MVC企业级项目框架

    ASP.NET MVC企业级项目框架 MVC项目搭建笔记---- 项目框架采用ASP.NET MVC+Entity Framwork+Spring.Net等技术搭建,搭建过程内容比较多,结合了抽象工厂 ...

  7. 使用Visual Studio 2015 开发ASP.NET MVC 5 项目部署到Mono/Jexus

    最新的Mono 4.4已经支持运行asp.net mvc5项目,有的同学听了这句话就兴高采烈的拿起Visual Studio 2015创建了一个mvc 5的项目,然后部署到Mono上,浏览下发现一堆错 ...

  8. ASP.NET MVC搭建项目后台UI框架—1、后台主框架

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  9. ASP.NET MVC搭建项目后台UI框架—11、自动加载下拉框查询

    ASP.NET MVC搭建项目后台UI框架—1.后台主框架 需求:在查询记录的时候,输入第一个字,就自动把以这个字开头的相关记录查找出来,输入2个字就过滤以这两个子开头的记录,依次类推. 突然要用到这 ...

随机推荐

  1. IO之4种字节流拷贝文件方式对比

    public class CopyMp4Demo { public static void main(String[] args) throws IOException { long start = ...

  2. python包与模块导入

    一 .module 通常模块为一个文件,直接使用import来导入就好了.可以作为module的文件类型有".py".".pyo".".pyc&quo ...

  3. spring jpetstore研究入门(zz)

    spring jpetstore研究入门 分类: java2008-12-21 23:25 561人阅读 评论(2) 收藏 举报 springstrutsibatissearchweb框架servle ...

  4. cxf 介绍

    CXF 编辑     目录 1Apache CXF 简介 关于Apache CXF 功能特性 项目目标 2Apache CXF特点 灵活部署 支持多种编程语言 代码生成     1Apache CXF ...

  5. hadoop web管理界面不能打开问题

    centos 7 安装好hadoop的,hadoop和yarn都正常启动,但是yarn的web界面(8088),hdfs的web界面(50070)都不能打开,防火墙是处于关闭状态. 修改默认启动级别, ...

  6. ios 基础知识篇 堆和栈的区别

    前言 堆和栈是什么?有什么区别?是干嘛的? 内存管理 移动设备的内存及其有限,每一个APP所能占用的内存是有限制的 (吐槽一下:iPhone6s还是16G起步,还好我也买不起->_-> 扯 ...

  7. layer.alert没有垂直居中

    经查找是因为 <!DOCTYPE html> 这句没有写在整个页面的最顶部,将其放在整个页面的第一行就可以了. ps:原理不是很清楚

  8. Windows上使用Git管理文件

    今天在搜索ffmpeg相关资料时,需要通过.sh脚本文件下载git上的代码文件,最后通过在Windows上安装了git,并在git.bash中执行bash ffmpeg.sh解决了代码下载问题,顺便学 ...

  9. Mybatis在oracle数据库中插入数据后返回自增值ID

    1.将id设置成自增序列 CREATE OR REPLACE TRIGGER "DATALIB"."TRIG_USER_ADD" BEFORE INSERT O ...

  10. c# devexpress绘图 三角函数

    加标题: using System; using System.Windows.Forms; using DevExpress.XtraCharts; // ... namespace SideByS ...