繁体   English   中英

如何使用Entity Framework对象上下文执行事务?

[英]How to perform a transaction with an Entity Framework object context?

我使用Entity Framework 4创建了一个非常简单的数据库。我希望能够在实体上使用事务,但我似乎无法通过回滚来保持更改。 我真的只需要在将实体保存到数据库之前放弃对实体的临时更改。

例如,以下代码使用实体框架对象上下文“MusicContainer”。 在TransactionScope中,创建了一个Artist实体。 然后交易结束而没有完成; 所以我希望这个交易可以回滚。 但是,程序运行就像我从未创建过TransactionScope一样; 在TransactionScope结束后,music.SaveChanges()行将对象保存到数据库。

class Program
{
    static void Main(string[] args)
    {
        using (MusicContainer music = new MusicContainer())
        {
            using (TransactionScope transaction = new TransactionScope())
            {
                Artist artist = new Artist { Name = "Test" };
                music.Artists.AddObject(artist);
            }
            // The transaction ended without Complete(); shouldn't the changes be abandoned?
            music.SaveChanges();
        }
    }
}

如果实体框架没有像我期望的那样使用TransactionScope,我怎样才能获得我正在寻找的功能? 我有几种情况,函数的调用者在MusicContainer中传递,我需要在从函数返回之前将MusicContainer保持在干净状态(即回滚更改,以便他们不会意外地保存在另一个调用的SaveChanges中在同一个MusicContainer对象上)。

在这种情况下,您根本不需要TransactionScope ,只需要SaveChanges() - 如果您有另一个using MusicContainer using块,这将是一个单独的事务,并且不会保存当前using块中的任何更改。 只有跨越多个DB上下文的TransactionScope才需要TransactionScope

通常,上下文仅应用于由相关操作组成的工作单元,一旦完成调用SaveChanges() 为每个单独的,不相关的工作单元打开一个新的上下文。 话虽如此,只需在你的场景中使用它:

        using (MusicContainer music = new MusicContainer())
        {
                Artist artist = new Artist { Name = "Test" };
                music.Artists.AddObject(artist);
                music.SaveChanges();
        }

你的SaveChanges在错误的地方。

class Program
{
    static void Main(string[] args)
    {
        using (MusicContainer music = new MusicContainer())
        {
            using (TransactionScope transaction = new TransactionScope())
            {
                Artist artist = new Artist { Name = "Test" };
                music.Artists.AddObject(artist);
                music.SaveChanges();
            }
            // The transaction ended without Complete(); the changes are abandoned?
        }
    }
}

如果事务失败,则不应重用MusicContainer 为每个工作单元创建一个新的工作单元

实体框架应该能够使用TransactionScope 如果需要回滚仅通过此方法使用的更改,则需要启动New TransactionScope。

 using (MusicContainer music = new MusicContainer())
   {
     using (TransactionScope transaction = new TransactionScope(TransactionScopeOptions.RequiresNew))
          {
              Artist artist = new Artist { Name = "Test" };
              music.Artists.AddObject(artist);
              music.SaveChanges();
              scope.Complete(); 
          }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM