zoukankan      html  css  js  c++  java
  • EF中使用UnitOfWork

    前言

    关于EF5中使用UnitWork,参见另一博文:  https://www.cnblogs.com/masonblog/p/9801162.html

    每次提交数据库都会打开一个连接,造成结果是:多个连接无法共用一个数据库级别的事务,也就无法保证数据的原子性、一致性。
    解决办法是:在ObjectContext的CRUD操作基础上再包装一层,提供统一的入口,让服务层调用。
    同一个UnitOfWork实例对象下所有的ObjectContext都共同一个数据库上下文对象(ps:EF用的是ObjectContext),也就是共用一个事物。
    提交数据库时,只要有一个操作失败,那么所有的操作都被视为失败。
    实际使用:https://www.cnblogs.com/masonblog/p/9563199.html
    代码托管:https://github.com/catbiscuit/AutofacStudy

    实现过程

    实体层

     删除其中的两个.tt文件,然后在edmx页面,右键点击属性,将属性中的代码生成策略 从"无"修改为"默认值"。

    数据访问层

    Teacher表示例

    IDAL层

    直接继承IDALBase<T>泛型接口,其中定义了一些基础的方法。

    namespace Apps.IDAL
    {
        public interface ITeacherDAL : IDALBase<Teacher>
        {
        }
    }

    DAL层

    直接继承DALBase<T>类,和ITeacherDAL接口。
    DALBase类,需要提供实体类和数据库上下文。因为需要创建一个统一管理数据库操作的对象。

    namespace Apps.DAL
    {
        public class TeacherDAL : DALBase<Teacher, AutofacDBEntities>, ITeacherDAL
        {
            public TeacherDAL(IDatabaseFactory<AutofacDBEntities> databaseFactory)
                : base(databaseFactory)
            {
    
            }
        }
    }

    IBLL层

    定义基本的数据操作方法。

    namespace Apps.IBLL
    {
        public interface ITeacherBLL
        {       
            bool Add(Teacher entity);
    
            bool Delete(Teacher entity);
    
            bool Update();
    
            Teacher GetModelByCondition(Expression<Func<Teacher, bool>> predicate);
    
            IQueryable<Teacher> GetList(Expression<Func<Teacher, bool>> predicate,
                Expression<Func<Teacher, object>> orderBy,
                bool isAscending);
    
            IQueryable<Teacher> GetList(Expression<Func<Teacher, bool>> predicate);
    
            Teacher GetModelBySql(string sql);
        }
    }

    BLL层

    对ITeacherBLL接口中方法的实现。

    namespace Apps.BLL
    {
        public class TeacherBLL : ITeacherBLL
        {
            private readonly ITeacherDAL _iTeacherDAL;
            private readonly IUnitOfWork<AutofacDBEntities> _uwork;
    
            public TeacherBLL(ITeacherDAL iTeacherDAL
            , IUnitOfWork<AutofacDBEntities> uwork)
            {
                this._iTeacherDAL = iTeacherDAL;
                this._uwork = uwork;
            }
    
            public bool Add(Teacher entity)
            {
                _iTeacherDAL.Add(entity);
                return _uwork.Commit() > 0;
            }
            public bool Delete(Teacher entity)
            {
                _iTeacherDAL.Delete(entity);
                return _uwork.Commit() > 0;
            }
    
            public bool Update()
            {
                return _uwork.Commit() > 0;
            }
    
            public Teacher GetModelByCondition(Expression<Func<Teacher, bool>> predicate)
            {
                return _iTeacherDAL.GetModelByCondition(predicate);
            }
    
            public IQueryable<Teacher> GetList(Expression<Func<Teacher, bool>> predicate
            , Expression<Func<Teacher, object>> orderBy
            , bool isAscending)
            {
                return _iTeacherDAL.GetList(predicate, orderBy, isAscending);
            }
    
            public IQueryable<Teacher> GetList(Expression<Func<Teacher, bool>> predicate)
            {
                return _iTeacherDAL.GetList(predicate);
            }
    
            public Teacher GetModelBySql(string sql)
            {
                return _iTeacherDAL.GetModelBySql(sql);
            }
        }
    }

    注意

    第一:类中定义了一个IUnitOfWork泛型对象,这个就是单元事务的管理对象。

    DAL层只是将对数据的操作,添加到一个数据缓存的集合中。

    当数据操作的步骤完成时,才调用IUnitOfWork泛型对象进行数据操作的提交。

    这样确保了原子性和一致性。

    第二:Update操作,BLL并没有将数据的操作添加到数据缓存的集合中。

    此处,可以通过单步调试,当执行到UnitOfWork类中时,

    监视DbContext对象的值,这个对象会监视数据库上下文中数据的状态。

    这个地方,就要求Update操作的对象只能是从数据库获取得来。

    使用lambda表达式获取实体。

    示例操作:

    Model model =  DAL.GetModel(2);

    model.Name = "修改Name";

    BLL.Update();

    此时BLL层执行update方法,实际上只是执行了单元事务的提交,也就完成了对该条记录的修改。

    但是,如果是实例化的对象是无法修改数据。

    Model model = new Model();

    model.ID = 2;

    model.Name = "修改Name";

    BLL.Update();

    这样执行更新操作,是无法修改数据的

    总结

    DAL层,只是将数据的操作(新增修改删除)附加到数据库上下文中。

    UnitOfWork,才是将数据进行提交的地方。

    所以,BLL层的方法才能实现对数据的完成操作。

  • 相关阅读:
    OpenCV-C++ 图像上采样和降采样
    OpenCV-C++ 图像形态学操作应用-提取水平与垂直线
    OpenCV-C++ 图像形态学操作
    OpenCV-C++ 图像滤波(二)-中值滤波-双边滤波
    OpenCV-C++ 图像滤波(一)-均值滤波-高斯滤波
    OpenCV-C++ 绘制基本形状与编写文字
    OpenCV-C++ 调整图像亮度和对比度
    OpenCV-C++ 图像混合
    Mysql新建表,插入中文时报错“Incorrect string value: 'xE4xBDxA0xE5xA5xBD' for column”问题
    springcloud11 spring cloud config
  • 原文地址:https://www.cnblogs.com/masonblog/p/9565073.html
Copyright © 2011-2022 走看看