在EF中,数据上下文通常是DbContext或者ObjectContext,而在linq to sql中数据上下文则是DataContext,它们的作用是建立一个数据库映射对象ORM,以更加方便的操作数据库,而它们的创建工作,我在很长一段时间将它约束在DAL层,对BLL层不公开创建方法,但当我对.net了解更多之后,觉得将数据上下文的创建工作公开到BLL层是很有必要的,最起码在程序性能上及原子化操作上很有必要。
原来我们在BLL层调用一个添加操作时,需要在DAL层先去定义这个实现,即使这个实体只存在一个添加操作,你也要去实现一下,这无疑加大了代码量,像这样:
public class ProductRepository : TestBase{ #region Constructors public ProductRepository() { } public ProductRepository(IUnitOfWork db) : base((TestDataContext)db) { } #endregion /// /// 一个方法,也要建立这个repository,有点坏味道 /// /// public override void Insert(Product entity) { base.Insert(entity); } }
而,如果我们将数据上下文创建的工作公开到BLL层,那结果就不一样了,再配合IUnitOfWork思想,实现在BLL层对DAL方法的整合,实现向数据库发送一次连接请求,这种感觉,酷D了,呵呵。
public abstract class BLLBase { protected IUnitOfWork IUnitOfWork { get; private set; } public BLLBase() : this(null) { } public BLLBase(IUnitOfWork iUnitOfWork) { IUnitOfWork = iUnitOfWork; } protected ICompleteRepositoryLoadRepository () where T : class { return IUnitOfWork == null ? new TestBase () : new TestBase (IUnitOfWork); } }
对于BLL层的祖宗,呵呵,BLLBas,它将数据上下文的创建工作在架造方法中注入,然后传递给LoadRepository这generic method,在BLL层的业务类中可以
继承它并为数据上下文进行实例化,再使用LoadRepository直接对数据表进行CURD操作,一切就是这样简单,看代码:
#region BLLBase中直接调用公用方法 IUnitOfWork.IsNotSubmit = true; new OrderRepository(IUnitOfWork).Insert(order); if (product != null) LoadRepository().Insert(product); IUnitOfWork.SaveChanges(); #endregion
OK,UI层直接调用BLL层的具体业务方法即可,下面我们再来看一个我DAL层的类结构,有时,我越得类结构图比代码更能说明问题:
CURD操作规范:
DAL层Repository模式实现:
IUnitOfWork工作单元规范: