c# - 跨多个上下文共享 EF 中的连接和事务(UnintentionalCodeFirstException)

标签 c# entity-framework

以前的版本和问题在下面作为附加上下文提供。改进后的问题表述和问题如下:

  • 如何在 EF 6.1.0 数据库和 .NET 4.5.2 中的多个上下文之间共享事务而不执行分布式事务?

为此,看起来我需要在多个上下文之间共享连接,但到目前为止我一直在查看的代码示例和教程并没有那么富有成效。问题似乎是围绕如何定义连接对象和事务对象类型的功能组合,以便在构建对象上下文时也构建和找到 EF 数据库优先对象元数据。

也就是说,我想做类似于 EF 6.n 教程 here 中描述的事情。一些示例代码可以是

int count1;
int count2;
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) 
{ 
    //How to define this connection so as not to run into UnintentionalCodeFirstException?
    //Creating a dummy context to obtain the connectiong string like so
    //dummyContext.Database.Connection.ConnectionString  and then using the connection will be greeted with the aforementioned exception.      
    using(var conn = new SqlConnection("...")) 
    {
        using(var c1 = new SomeEntities(conn, contextOwnsConnection: false))
        {
            //Use some stored procedures etc.
            count1 = await c1.SomeEntity1.CountAsync();
        }

        using(var c2 = new SomeEntities(conn, contextOwnsConnection: false))
        {
            //Use some stored procedures etc.
            count2 = await c2.SomeEntity21.CountAsync();
        }
    }
}   

int count = count1 + count2;

在示例中还有其他关于如何创建共享连接和事务的方法,但正如所写,罪魁祸首似乎是,如果我在(“...”中提供连接字符串部分)前面的片段作为 dummyContext.Database.Connection.ConnectionString 我会得到一个异常(exception)。


当我尝试跨多个 EF 上下文共享事务时,我不确定我是否只是阅读了错误的来源,或者我的代码中是否存在其他错误。怎么做到的?

我已经阅读了很多关于此的其他 SO 帖子(例如 this )和一些 tutorials 。他们没有帮助。

我有一个奇怪的问题,看起来我没有像其他教程和帖子中那样定义构造函数重载。也就是说,采用链接的教程链接,我无法编写 new BloggingContext(conn, contextOwnsConnection: false)) 并使用共享连接和外部事务。

那如果我写

public partial class SomeEntities: DbContext
{
    public SomeEntities(DbConnection existingConnection, bool contextOwnsConnection): base(existingConnection, contextOwnsConnection) { }
}

并像在教程中一样使用它,我从以下 T4 模板生成的代码中的以下行中得到异常

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    throw new UnintentionalCodeFirstException();
}

我使用的是 .NET 4.5.2 和 EF 6.1.0。我从现有数据库构建了 edmx 并从那里生成了代码。在这种特殊情况下,我使用任务并行线程来加载数十个 SQL Server Master Data Services 暂存表(是的,一个大模型)并调用相关过程(由每个表一个的 MDS 提供)。 MDS 有自己的补偿逻辑,以防某些表的暂存失败,但回滚事务也应该是可行的。看起来我的 EF 有一个(奇怪的)问题。

<附录:史蒂夫建议直接使用 TransactionScope。没有需要分布式事务的共享连接,这不是我可以选择的选项。然后,如果我尝试为上下文提供共享连接(教程中显示的一些选项,一个 here 我遇到了“缺少构造函数”的问题。当我定义一个时,我得到了我在代码中引用的异常。总而言之, 这感觉很奇怪。也许我生成 DbContext 和相关类的方式有问题。

<注意 1: 看起来根本原因与 Arthur(EF 开发团队成员)Don't use Code First by mistake 的这篇博文中一样。也就是说,在数据库优先开发中,框架会寻找连接字符串中定义的类关系映射。我的连接字符串中有可疑的东西是..?

最佳答案

您是否尝试过将调用包装在事务范围内?

using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted }))
{

    // Do context work here
    context1.Derp();
    context2.Derp();

    // complete the transaction
    scope.Complete();
}

关于c# - 跨多个上下文共享 EF 中的连接和事务(UnintentionalCodeFirstException),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23937587/

相关文章:

c# - 具有多对多不加载集合属性的实体

entity-framework - 使用 Web API 上的 Autofac 对 EF 进行依赖注入(inject)

c# - Entity Framework 单个漂亮的错误消息

c# - DropDownList 导致错误 : Object reference not set to an instance of an object

c# - TextBox 不支持系统十进制(点或逗号)

c# - 在单词互操作中使用选择和范围

c# - 如何在 Visual Studio 的其他项目中使用 SQL Server 数据库项目?

c# - WPF Windows 8 兼容性问题

c# - Dynamically Flat C# object class 运行时的属性列表

c# - 从 Entity Framework 实体获取列数据类型