你的位置:首页 > 软件开发 > ASP.net > 在EntityFramework6中管理DbContext的正确方式——2DbContext的默认行为(外文翻译)

在EntityFramework6中管理DbContext的正确方式——2DbContext的默认行为(外文翻译)

发布时间:2016-05-06 22:00:16
(译者注:使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gueddari对此做了深入研究和优秀的工作并且写了一篇优秀的文章,现在我将其翻译为 ...

(译者注:使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gueddari对此做了深入研究和优秀的工作并且写了一篇优秀的文章,现在我将其翻译为中文分享给大家。由于原文太长,所以翻译后的文章将分为四篇。你看到的这篇就是是它的第二篇。原文地址:http://mehdi.me/ambient-dbcontext-in-ef6/)

DbContext的默认行为

通常来说,DbContext的默认行为可以被描述为:“默认情况下就能做正确的事”。

下面是你应该记在脑海里面的几个关于EntityFramework的重要行为。这个列表描述了EF访问SqlServer的行为。用其它的数据库可能会略有差异。

DbContext不是get='_blank'>线程安全的

你千万不要从多个线程同时去访问DbContext派生类实例。这可能导致将多个查询通过一个相同的数据库连接被同时发送了出去——它将破坏DbContext维护的一级缓存的状态——它们被用来提供标识映射(Identity Map),变更追踪和工作单元的功能。

在一个多线程应用程序中,你必须为每一个线程创建一个独立的DbContext派生类实例。

问题来了,如果DbContext不是线程安全的,那么它怎么支持EF6的异步功能呢?其实很简单:只需要保证在任何时刻只有一个异步操作被执行(就像EF的支持异步模式的规范描述的那样)。如果你尝试在同一个DbContext实例上并发的执行多个操作,比如通过DbSet<T>.ToListAsync()方法并发地执行多个查询语句,你将会得到一个带有下面消息的NotSupportedException。

  A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.

EF的异步功能是为了支持异步编程模型,而不是并发编程模型。

当且仅当SaveChanges()方法被调用的时候,修改才会被持久化

任何对实体的修改,包括更新,插入或者删除,当且仅当DbContext.SaveChanges()被调用的时候才会被持久化到数据库。如果DbContext实例在SaveChanges()方法被调用之前就被释放掉了,那么这些更新操作,插入操作,删除操作没有一条能持久化到底层数据库。

下面是用EF来实现一个业务事务的规范方式:

           

 using (var context = new MyDbContext(ConnectionString))      {        /*         * 业务逻辑放在这儿. 通过context添加,修改,删除数据。        *         * 抛出任何异常就可以回滚所有变化。        *         * 直到业务事务完成,否则不能调用SaveChanges()方法        * 也就是说不能部分或者中间保存。        * 每一个业务事务只能刚好调用一次SaveChanges()方法 。        *        * 如果你发现你自己需要在一个业务事务里面多次调用        * SaveChanges()方法,那就意味着你在一个服务方法        * 里面实现多个业务事务。这绝对是灾难的“必备良药”。         * 调用你的服务的客户端会很自然的假定你的服务方法        * 以原子的行为提交或者回滚——但你的服务却可能        * 部分提交,让系统处于一个不一致的状态。         *        * 在这种情况下,将你的服务方法重构成多个服务方法——        * 每一个服务方法刚好实现了刚好一个业务事务。                          */        [...]        // 完成业务事务并且持久化所有变化 。        context.SaveChanges();        // 在这行代码之后变化不可能回滚了。        // context.SaveChanges()应当是任何业务事务        // 的最后一行代码。      }

原标题:在EntityFramework6中管理DbContext的正确方式——2DbContext的默认行为(外文翻译)

关键词:

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录