前言

关于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层的方法才能实现对数据的完成操作。

EF中使用UnitOfWork的更多相关文章

  1. EF5中使用UnitOfWork

    前言 每次提交数据库都会打开一个连接,造成结果是:多个连接无法共用一个数据库级别的事务,也就无法保证数据的原子性.一致性. 解决办法是:在ObjectContext的CRUD操作基础上再包装一层,提供 ...

  2. 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...

  3. 2.EF中 Code-First 方式的数据库迁移

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/code-first-migrations-with-entity-framework/ 系列目 ...

  4. EF中扩展出Between操作符 (修订版)

    随手记录一下,这是针对原文错误的修改. 原文:EF中扩展出Between操作符 直接使用是错误的,修改后的扩展方法: /// <summary> /// 扩展 Between 操作符 // ...

  5. 如何在EF中实现left join(左联接)查询

    在EF中,当在dbset使用join关联多表查询时,连接查询的表如果没有建立相应的外键关系时,EF生成的SQL语句是inner join(内联),对于inner join,有所了解的同学都知道,很多时 ...

  6. EF中执行sql语句,以及事务

    EF to sql string sql = "select T_Task.BSID,T_Task.CloseDate,T_Task.CompleteDate,T_Task.CloseUse ...

  7. EF架构~在ef中支持IQueryable级别的Contains被翻译成了Exists,性能可以接受!

    回到目录 Entityframeworks很聪明 不错,非常不错!ef里的contains比linq to sql里的contains有了明显的提升,事实上,是在进行SQL语句翻译上有所提升,在lin ...

  8. DB表的关系及EF中Fluent API的使用

    现在使用多数的数据库是关系型数据库,那么表与表之间的关系就会显得尤其重要,对于数据的CRUD处理和以后数据的分析有很大的好处.下面是对于数据库中对表关系的理解以及在EF中使用Fluent API来创建 ...

  9. EF 中事务的书写

    在EF 中怎么使用事务? 这个问题纠结了我好久,直到有人跟我一起讨论,我和同事一起讨论查资料. 查的好多资料都是使用 using (TransactionScope scope = new Trans ...

随机推荐

  1. 免费AWS云服务器一键搭建Trojan详细教程

    前言 想要撸AWS服务器的可以看我上一篇博客,这里就不介绍了,以下步骤有问题的朋友可以私信或者评论区留言. 配置AWS云服务器 选择语言,博主写了博客后才看到,前面都是使用谷歌翻译. 选择地区 创建虚 ...

  2. Java蓝桥杯——贪心算法

    贪心算法 贪心算法:只顾眼前的苟且. 即在对问题求解时,总是做出在当前看来是最好的选择 如买苹果,专挑最大的买. 最优装载问题--加勒比海盗 货物重量:Wi={4,10,7,11,3,5,14,2} ...

  3. 解决YUM下Loaded plugins: fastestmirror Determining fastest mirrors 的错误问题

    最近想再购买一台虚拟服务器做项目测试,之前在西部数码购买的已经过期了,在同事的推荐下去搬瓦工购买了一台服务器,听他介绍在这里购买服务器很便宜($19.99/年)而且还是国外的,看着相比之前的确实挺便宜 ...

  4. [原理] Android Native内存泄漏检测原理解析

    转载请注明出处:https://www.cnblogs.com/zzcperf/articles/11615655.html 上一篇文章列举了不同版本Android OS内存泄漏的检测操作(传送门), ...

  5. 阿里云云开发平台助力风变科技Serverless架构升级实战

    阿里云云开发平台助力风变科技Serverless架构升级实战 背景 风变科技 一个希望通过技术去推动下一代基础教育的组织.旗下产品包括第一代的熊猫书院(读书类产品).第二代的熊猫小课(泛学科综合学习平 ...

  6. VisualStudio 编写汇编代码相关设置

    VS编写汇编代码方法 新建空项目,不创建解决方案 项目右键,Build Customizations,选择masm 新建源文件,后缀为.ASM 编写代码 .386 ; Tells MASM to us ...

  7. EntityFramework Core健康检查

    前言 .NET Core提供对应方法可进行健康检查,那么在EF Core中是否也提供了相应的方式呢?EF Core 2.2+(包含2.2)版本提供了针对上下文的健康检查,接下来我们直接利用.NET 5 ...

  8. Cys_Control(一) 项目搭建

    一.基础工程搭建 Cys_Controls Cys_Resource(注:一般类库默认不能引入资源文件,故直接创建Custom Control Library) Cys_Demo 删除默认文件夹及类, ...

  9. 第二十七章、containers容器类部件QTabWidget选项窗部件详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 容器部件就是可以在部件内放置其他部件的部件,在Qt Designer中可以使用的容器部件有 ...

  10. 问题:PyCharm调试方法Force run to cursor与run to cursor的区别

    Force run to cursor与run to cursor的差别是,后者在执行到光标的代码行前,如果有代码中设置了断点,会在该断点处暂停,等待进一步调试指令,而Force run to cur ...