1. 程式人生 > >ASP.Net MVC OA專案筆記<六>

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