說(shuo)說(shuo)IUnitOfWork~DbContext對象的創(chuang)建應該向BLL層公開
在EF中,數據上下文通常是DbContext或者ObjectContext,而在linq to sql中數據上下文則是DataContext,它們的作用是建立一個數據庫映射對象ORM,以更加方便的操作數據庫,而它們的創建工作,我在很長一段時間將它約束在DAL層,對BLL層不公開創建方法,但當我對.net了解更多之后,覺得將數據上下文的創建工作公開到BLL層是很有必要的,最起碼在程序性能上及原子化操作上很有必要。
原來我(wo)們在(zai)BLL層(ceng)調用一(yi)個(ge)添加操(cao)作時(shi),需要在(zai)DAL層(ceng)先去(qu)定義這個(ge)實現(xian),即使這個(ge)實體只存在(zai)一(yi)個(ge)添加操(cao)作,你也要去(qu)實現(xian)一(yi)下,這無疑加大了代碼量,像這樣:
public class ProductRepository : TestBase<Product> { #region Constructors public ProductRepository() { } public ProductRepository(IUnitOfWork db) : base((TestDataContext)db) { } #endregion /// <summary> /// 一個(ge)(ge)方法,也要建立這個(ge)(ge)repository,有點壞味(wei)道 /// </summary> /// <param name="entity"></param> public override void Insert(Product entity) { base.Insert(entity); } }
而(er),如果我(wo)們(men)將(jiang)數據上下文創(chuang)建的工(gong)作公開到BLL層,那結(jie)果就不一樣了,再配合IUnitOfWork思(si)想,實現(xian)(xian)在BLL層對DAL方法的整(zheng)合,實現(xian)(xian)向數據庫發(fa)送一次連接請求,這(zhe)種感覺,酷D了,呵呵。
public abstract class BLLBase { protected IUnitOfWork IUnitOfWork { get; private set; } public BLLBase() : this(null) { } public BLLBase(IUnitOfWork iUnitOfWork) { IUnitOfWork = iUnitOfWork; } protected ICompleteRepository<T> LoadRepository<T>() where T : class { return IUnitOfWork == null ? new TestBase<T>() : new TestBase<T>(IUnitOfWork); } }
對于(yu)BLL層的祖(zu)宗,呵呵,BLLBas,它將(jiang)數據上下文的創建工作在架造方法(fa)中注入,然后傳遞給LoadRepository這generic method,在BLL層的業務類(lei)中可以
繼承(cheng)它并為數據上下文進行實例(li)化,再使用LoadRepository直接對數據表進行CURD操作,一切就是(shi)這樣簡(jian)單,看代(dai)碼:
#region BLLBase中直接調用公用方法 IUnitOfWork.IsNotSubmit = true; new OrderRepository(IUnitOfWork).Insert(order); if (product != null) LoadRepository<Product>().Insert(product); IUnitOfWork.SaveChanges(); #endregion
OK,UI層直接調(diao)用BLL層的具體業務方法即可(ke),下面我(wo)們再來看一(yi)個我(wo)DAL層的類結(jie)構(gou),有時(shi),我(wo)越得(de)類結(jie)構(gou)圖比代碼更能說明問題:
CURD操作規范:
DAL層Repository模式(shi)實(shi)現:
IUnitOfWork工作單元規(gui)范: