用工作單元帶給我們的是什么?... 1
1. 相關說明 2. 優化查詢 3. 優化SubmitChanges 4. 優化TransactionScope 5. 核心代碼
1. 相關說明
工作單元的接入,保證了數據上下文在一個操作單元中只有一個,它可以通過構造方法注入到其它類中,實現跨類進行方法的組合。
2. 優化查詢
上面的問題產生的場合應該是:
你用了join語句,你的join語句與from語句所使用的數據上下文不是一個(DataContext)
解決方法:
將數據上下文變成一個就可以了,這就是之前我們一直用的線程單例模式出現的原因,而往往一個方法可能需要引用多個類中的方法,這時,線程單例將不能解決這個問題,這時,出現了IunitOfWork,工作單元的概念!
使用的場合:
BLL層引用多個BLL層的方法
BLL層引用多個DAL層的方法
可能出現的代碼:
3. 優化SubmitChanges
將多個SubmitChanges語句合並成一個,然后提交意味着什么?它意味着你與數據庫交互次數的降低,呵呵!
代碼可能是這樣:
4. 優化TransactionScope
對於不同數據上下文組合的事務來說,TransactionScope將會把它提升為分布式事務,這在MSDN上確實沒有找到相關文檔,只是實踐證明出來的,呵呵,所以,對於使用TransactionScope的開發者來說,請同時使用IUnitOfWork模式吧,讓不必出現的MSDTC不要隨意出現!
5. 核心代碼
BLL層基類:
/// <summary> /// 業務層抽象基類 /// </summary> public abstract class BLLBase { #region Constructors public BLLBase() : this(null) { } public BLLBase(IUnitOfWork iUnitOfWork) { this.UnitOfWork = iUnitOfWork; this.VMessage = new VMessage(); } #endregion #region Fields & Properties /// <summary> /// 工作單元對象,由子類初始化 /// </summary> protected IUnitOfWork UnitOfWork { get; private set; } /// <summary> /// XXB連接串 /// </summary> protected static string XXBConn { get { if (System.Configuration.ConfigurationManager.ConnectionStrings["xxb"] == null) throw new ArgumentException("請配置在config文件中的XXB節點"); return System.Configuration.ConfigurationManager.ConnectionStrings["xxb"].ToString(); } } /// <summary> /// 通用消息 /// </summary> protected VMessage VMessage { get; set; } #endregion #region Methods /// <summary> /// 數據層統一操作對象實例 /// 避免派生類直接new對象 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="iUnitOfWork"></param> /// <returns></returns> protected ICompleteRepository<TEntity> LoadRepository<TEntity>() where TEntity : class,Entity.IDataEntity { return UnitOfWork == null ? new EEE114Repository<TEntity>() : new EEE114Repository<TEntity>(UnitOfWork); } #endregion }
BLL層業務類繼承BLLBase,可以使用LoadRepository泛型方法直接操作實體對象,如果BLL層業務對象為業務復雜的,在將來可能需要互相引用對方的,這時,我們需要在BLL類中進行構造方法的重構,為IUnitOfWork實例的注入預留接口。
#region Constructors public User_CourseManager() : this(null) { } public User_CourseManager(IUnitOfWork iUnitOfWork) : base(iUnitOfWork) { res_ItemCategory = new DAL.Res_ItemCategory(UnitOfWork); iResourceService = new Res_ItemService(); user_CourseRepository = new DAL.User_Course(UnitOfWork); iCommon_CategoryServices = new BLL.Common_CategoryServices(UnitOfWork); } #endregion
有時,如果這個bll類需要使用BLLBase里的LoadRepository方法,需要為它的UnitOfWork屬性賦值,為了保持代碼的嚴禁性,我們只允許在基類構造方法中為它賦值,所以,一般bll子類的架構方法為:
public UserCenterManager() : base(new dbDataContext(XXBConn)) { _user_Info = new User_Info(UnitOfWork); _user_Profile = new User_Profile(UnitOfWork); _user_SchoolInfo = new User_SchoolInfo(UnitOfWork); }
上面的代碼中,同時展示了BLL是如何去引用DAL對象的,User_Info同時接收一個IunitOfWork對象,而它的代碼為:
public partial class User_Course : EEE114Base { public User_Course(IUnitOfWork iUnitOfWork) : base(iUnitOfWork) { }
事實上,它是將EEE114Base基類中傳遞了一個數據上下文,這些數據上下文都會繼承IunitOfWork這個接口,並最終實現統一的提交動作,我們在開發中,建議為每個DAL類型都保留一個帶有IunitOfWork參數的架構方法,這樣才能保存我們的LINQ操作共處於一個數據上下文。