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==2); 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(); } }