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. 繁体简体转化_langconv.py

    from copy import deepcopyimport re try: import psyco psyco.full()except: pass try: from zh_wiki impo ...

  2. Two Sum II - Input array is sorted LT167

    Given an array of integers that is already sorted in ascending order, find two numbers such that the ...

  3. Sliding Window Median LT480

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  4. 使用vmware安装ubuntu不能上网

    桌面版的话,进入桌面后还可以配置,服务版,我是在安装过程中提示的网络配置时候按照下面的方法手动配置的 安装虚拟机时候要安装网络服务,有的虚拟机在安装过程中可能已经安装好了,主机保持VMware NAT ...

  5. 浅谈System.gc()

      今天巩固给大家讲讲System.gc().Java的内存管理着实给各位编程者带来很大的方便,使我们不再需要为内存分配烦太多神.那么讲到垃圾回收机制,就不得不讲讲System.gc().   先简单 ...

  6. Linux常见目录使用区别

    /bin 在有的Unix和Linux系统中是/usr/bin的链接,不过UBuntu系统是两个独立的目录./bin 存放系统管理员和普通用户都要使用的程序. /sbin 存放用于系统恢复,系统启动,系 ...

  7. java保存繁体字到数据库时就报错Incorrect string value: '\xF0\xA6\x8D\x8B\xE5\xA4...' for column 'name' at row 1

    问题分析 普通的字符串或者表情都是占位3个字节,所以utf8足够用了,但是移动端的表情符号占位是4个字节,普通的utf8就不够用了,为了应对无线互联网的机遇和挑战.避免 emoji 表情符号带来的问题 ...

  8. (12)We should aim for perfection — and stop fearing failure

    https://www.ted.com/talks/jon_bowers_we_should_aim_for_perfection_and_stop_fearing_failure/transcrip ...

  9. EF对应null的处理

    原来的代码是 if (string.IsNullOrWhiteSpace(seal)) seal = null; ctx.Terminal.FirstOrDefault(ent=>ent.Sea ...

  10. c语言const和c++const

    1.常量 常量是指值不能被改变的量,又叫做字面值 1.1常量分类 1)字符常量:'a', 'A', '*'. 2)字符串常量:"helloworld","ilovechi ...