我正在开发一个包含100多个模块的大型应用程序,数据库中有近500个表。我们正在使用Entity Framework 4.2 Code First将此应用程序转换为WPF / WCF。我们的数据库是SQL Anywhere 11.由于数据库的大小,我们使用类似于Bounded DbContexts的方法,如Julie Lerman所述http://msdn.microsoft.com/en-us/magazine/jj883952.aspx。 我们的每个模块都创建自己的DbContext,只对所需的数据库子集进行建模。
但是,我们遇到了DbContexts创建方式的严重问题。我们的模块不是完全独立的,也不是。一些包含从其他几个模块调用的操作。当它们存在时,它们需要参与由调用模块启动的事务。 (并且出于体系结构的原因,DTC不是我们的选择。)在我们的旧ADO架构中,为了支持事务,将模块之间的开放连接传递给模块没有问题。
我查看了各种DbContext构造函数重载,并尝试从EntityConnection和StoreConnection管理事务,据我所知,没有组合允许ModuleA开始事务,在ModuleB中调用函数,让ModuleB的DbContext参与交易。
归结为两件简单的事情:
案例1.如果我使用DbContextA的EntityConnection构造DbContextB,则DbContextB不是使用自己的模型元数据构建的;它重用了DbContextA的元数据。由于上下文具有不同的DbSet集合,因此所有ModuleB的查询都会失败。 (实体类型不是当前上下文的一部分。)
案例2.如果我使用ModuleA的StoreConnection构造DbContextB,则DbContextB无法识别EntityConnection级别的StoreConnection的打开事务,因此当ModuleB调用SaveChanges()时,EF会尝试启动新事务。由于数据库连接实际上具有打开的事务,因此会生成数据库异常。 (Connection不支持并行事务。)
有没有办法1)强制DbContextB在案例1中构建自己的模型,或2)在案例2中获取DbContextB的ObjectContext以尊重其StoreConnection的事务状态?
(顺便说一下,我在EF6 alpha中看到了一些令人鼓舞的事情,但在测试之后,发现唯一的区别是我可以在开放连接上创建DbContextB。但即便如此,上述两个问题仍然存在。 )
答案 0 :(得分:0)
我建议您尝试使用TransactionScope
对象为您管理此任务。只要您的所有DbContexts
使用相同的连接字符串(非连接对象),交易就不应该尝试登记MS-DTC。