我使用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对象上。)
答案 0 :(得分:7)
在这种情况下,您根本不需要TransactionScope
,只需要SaveChanges()
- 如果您有另一个using
阻止MusicContainer
,这将是在单独的事务中,不会保存当前using
块中的任何更改。只有跨越多个DB上下文的事务才需要TransactionScope
。
一般情况下,上下文仅应用于由相关操作组成的工作单元,一旦完成调用SaveChanges()
。为每个单独的,不相关的工作单元打开一个新的上下文。话虽如此,只需在你的场景中使用它:
using (MusicContainer music = new MusicContainer())
{
Artist artist = new Artist { Name = "Test" };
music.Artists.AddObject(artist);
music.SaveChanges();
}
答案 1 :(得分:2)
你的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
。为每个Unit of Work
答案 2 :(得分:0)
实体框架应该能够使用 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();
}
}