4

There is an answer here to explain how to do transactions with Entity Framework However the solution does not work with code first. I have experimented and my tests indicate the following does work

using (var scope = new TransactionScope())
{
        DBContext1.SaveChanges()
        If (ForceFailure) return 0  // used in testing
        DBContext2.SaveChanges()
        scope.Complete();
 }

However I feel nervous because I am no longer passing parameters to SaveChanges or calling AcceptAllChanges

How do I establish whether I can trust my solution?

Community
  • 1
  • 1
Kirsten
  • 15,730
  • 41
  • 179
  • 318
  • What aspect (DB consistency, context consistency, etc.) do you not trust? – Adam Robinson Feb 18 '13 at 20:37
  • I want to know that either both savechanges run or neither runs. My tests indicate that this is the case. However because the code seems so different to the earlier EF version, I am looking for some peer or documented validation. – Kirsten Feb 18 '13 at 20:50

1 Answers1

2

SaveChanges(Boolean) is part of ObjectContext, not DbContext. Note that the method SaveChanges(Boolean) in ObjectContext is deprecated in favor of SaveChanges(SaveOptions).

If you still want to use DbContext, you may be able to overload its own SaveChanges method to use IObjectContextAdapter.ObjectContext, by using an extension method for example.

asunrey
  • 875
  • 2
  • 10
  • 28
tne
  • 7,071
  • 2
  • 45
  • 68
  • 1
    DbContext does have a SaveChanges method – Kirsten Apr 11 '13 at 00:28
  • It does, but it isn't the same method (`DbContext` doesn't extend `ObjectContext`), which is why it lacks the arguments you need. You can, however, retrieve a reference to the `ObjectContext` used internally by the `DbContext` via the `IObjectContextAdapter` interface that `DbContext` implements, and use the `SaveChanges` method you need. – tne Apr 11 '13 at 07:33
  • Can you tell me where you found that the DBContext SaveChanges is deprecated? I have found references that it is the other way around - but not from Microsoft. – Kirsten Apr 11 '13 at 09:57
  • 1
    I'm talking about `SaveChanges(Boolean)` from `ObjectContext`, not the one from `DbContext`. Let me clarify: There are two methods, `ObjectContext.SaveChanges` and `DbContext.SaveChanges`. `ObjectContext.SaveChanges` is overloaded, and one of its variants (the one which accepts a boolean) is deprecated in favor of another (the one which accepts `SaveOptions`). This has nothing to do with `DbContext.SaveChanges`. – tne Apr 11 '13 at 11:06
  • Thanks for the clarification. Are you able to tell me whether objectContext.SaveChanges with SaveOptions is better than DBContext.SaveChanges and if so why? – Kirsten Apr 13 '13 at 16:23
  • 2
    `ObjectContext` and `DbContext` are really two different APIs, although with a similar goal. From what I gather, `DbContext` was created after `ObjectContext` to provide a simpler API mainly for code-first scenarios (removing the need for some boilerplate that `ObjectContext` requires) -- in fact, as I already hinted at, `DbContext` actually uses an `ObjectContext` internally, so it's effectively a wrapper. There may be other reasons, see http://stackoverflow.com/search?q=objectcontext+vs+dbcontext. In theory you shouldn't need `ObjectContext.SaveChanges`, but you may have hit a limitation. – tne Apr 15 '13 at 06:48
  • This has been deprecated in more recent versions of the framework. `SaveChanges(Boolean)` has been replaced by `SaveChanges(SaveOptions)`, which still needs to be referenced from `IObjectContextAdapter.ObjectContext` in code first. – Michael Brown Oct 13 '17 at 03:57