用工作單元(IUnitOfWork)帶給我們的是什么?
用工作單元帶給我們的是什么?... 1
1. 相關(guān)說明2. 優(yōu)化查詢3. 優(yōu)化SubmitChanges4. 優(yōu)化TransactionScope5. 核心代碼
1. 相關(guān)說明
工作單元的接入,保證了數(shù)據(jù)上下文在一個(gè)操作單元中只有一個(gè),它可以通過構(gòu)造方法注入到其它類中,實(shí)現(xiàn)跨類進(jìn)行方法的組合。
2. 優(yōu)化查詢
上面的問題產(chǎn)生的場合應(yīng)該是:
你用了join語句,你的join語句與from語句所使用的數(shù)據(jù)上下文不是一個(gè)(DataContext)
解決方法:
將數(shù)據(jù)上下文變成一個(gè)就可以了,這就是之前我們一直用的線程單例模式出現(xiàn)的原因,而往往一個(gè)方法可能需要引用多個(gè)類中的方法,這時(shí),線程單例將不能解決這個(gè)問題,這時(shí),出現(xiàn)了IunitOfWork,工作單元的概念!
使用的場合:
BLL層引用多個(gè)BLL層的方法
BLL層引用多個(gè)DAL層的方法
可能出現(xiàn)的代碼:
3. 優(yōu)化SubmitChanges
將多個(gè)SubmitChanges語句合并成一個(gè),然后提交意味著什么?它意味著你與數(shù)據(jù)庫交互次數(shù)的降低,呵呵!
代碼可能是這樣:
4. 優(yōu)化TransactionScope
對于不同數(shù)據(jù)上下文組合的事務(wù)來說,TransactionScope將會把它提升為分布式事務(wù),這在MSDN上確實(shí)沒有找到相關(guān)文檔,只是實(shí)踐證明出來的,呵呵,所以,對于使用TransactionScope的開發(fā)者來說,請同時(shí)使用IUnitOfWork模式吧,讓不必出現(xiàn)的MSDTC不要隨意出現(xiàn)!
5. 核心代碼
BLL層基類:
/// <summary> /// 業(yè)務(wù)層抽象基類 /// </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節(jié)點(diǎn)"); return System.Configuration.ConfigurationManager.ConnectionStrings["xxb"].ToString(); } } /// <summary> /// 通用消息 /// </summary> protected VMessage VMessage { get; set; } #endregion #region Methods /// <summary> /// 數(shù)據(jù)層統(tǒng)一操作對象實(shí)例 /// 避免派生類直接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層業(yè)務(wù)類繼承BLLBase,可以使用LoadRepository泛型方法直接操作實(shí)體對象,如果BLL層業(yè)務(wù)對象為業(yè)務(wù)復(fù)雜的,在將來可能需要互相引用對方的,這時(shí),我們需要在BLL類中進(jìn)行構(gòu)造方法的重構(gòu),為IUnitOfWork實(shí)例的注入預(yù)留接口。
#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
有時(shí),如果這個(gè)bll類需要使用BLLBase里的LoadRepository方法,需要為它的UnitOfWork屬性賦值,為了保持代碼的嚴(yán)禁性,我們只允許在基類構(gòu)造方法中為它賦值,所以,一般bll子類的架構(gòu)方法為:
public UserCenterManager() : base(new dbDataContext(XXBConn)) { _user_Info = new User_Info(UnitOfWork); _user_Profile = new User_Profile(UnitOfWork); _user_SchoolInfo = new User_SchoolInfo(UnitOfWork); }
上面的代碼中,同時(shí)展示了BLL是如何去引用DAL對象的,User_Info同時(shí)接收一個(gè)IunitOfWork對象,而它的代碼為:
public partial class User_Course : EEE114Base { public User_Course(IUnitOfWork iUnitOfWork) : base(iUnitOfWork) { }
事實(shí)上,它是將EEE114Base基類中傳遞了一個(gè)數(shù)據(jù)上下文,這些數(shù)據(jù)上下文都會繼承IunitOfWork這個(gè)接口,并最終實(shí)現(xiàn)統(tǒng)一的提交動作,我們在開發(fā)中,建議為每個(gè)DAL類型都保留一個(gè)帶有IunitOfWork參數(shù)的架構(gòu)方法,這樣才能保存我們的LINQ操作共處于一個(gè)數(shù)據(jù)上下文。
浙公網(wǎng)安備 33010602011771號