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