了解实体框架中的事务

nig*_*457 8 c# transactions transactionscope entity-framework-4

嗨,我试图与实体框架一起使用交易.由于在线提供了大量有关实施交易的不同方式的信息,我必须说我在正确的方式上有点困惑.我有一个带有两个表Employee和Company的示例数据库.Employee表有一个引用公司Id的外键.考虑到我想要实现一个事务,我将一条记录插入到Company表中,然后一条记录到Employee表,我想这样做,这样只有两个记录都成功时才插入记录我有以下代码.

public void addCompanyToDatabase()
    {
        using (var context = new myTestEntities())
        {
            context.Connection.Open(); //added this as was getting the underlying   
            //provider failed to open
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {
                    Company c = new Company();
                    c.Name = "xyz";
                    context.Companies.AddObject(c);
                    context.SaveChanges();

                    //int a = 0;
                    //int b = 5 / a;

                    Employee e = new Employee();
                    e.Age = 15;
                    e.Name = "James";
                    e.CompanyId = c.Id;
                    context.Employees.AddObject(e);
                    context.SaveChanges();

                    scope.Complete();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception Occurred");
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我想知道这是否是实现交易的正确方法.如果它是什么使用SaveChanges(false)scope.AcceptAllChanges()功能.任何信息都有帮助.

Ste*_*ven 14

在您的情况下,您不需要管理任何连接或事务:实体框架将为您执行此操作.当您不为EF提供已打开的连接(但具有连接字符串)时,它将打开连接并在调用期间启动事务context.SaveChanges().在该调用期间出现故障时,将回滚该事务.

换句话说,您的方法可以简单地看起来像这样:

public void addCompanyToDatabase()
{
    using (var context = new myTestEntities())
    {
        Company c = new Company();
        c.Name = "xyz";
        context.Companies.AddObject(c);

        Employee e = new Employee();
        e.Age = 15;
        e.Name = "James";
        e.CompanyId = c.Id;
        context.Employees.AddObject(e);

        // Only call SaveChanges last.
        context.SaveChanges();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在所有情况下,仍然不需要使用`TransactionScope`.如果您需要`TransactionScope`,因为您需要在多个数据库上进行原子操作,您的系统可能存在设计缺陷.我使用`TransactionScope'纯粹用于我的自动化集成测试.只需在`TransactionScope`中说出调用代码,就可以确保在测试结束时回滚所有(数据库)更改,而不必更改任何代码. (3认同)