11

OK, this may be a newbie question, but how/where can I subscribe to the ObjectContext.SavingChanges event as mentioned for example in this post.

I've only two relevant classes in my demo app: The "Country" class and a class which holds the EF Code First "definitions":

internal class TestDb : DbContext
{
    public DbSet<Country> Countries { get; set; }       
}

Any hint is highly appreciated.

Community
  • 1
  • 1
Mike
  • 1,992
  • 4
  • 31
  • 42

3 Answers3

10

You should be able to do this:

internal class TestDb : DbContext  
{  
    public void SetSavingChanges(EventHandler evt) 
    {
            var oc = this as IObjectContextAdapter;
            oc.ObjectContext.SavingChanges -= evt;
            oc.ObjectContext.SavingChanges += evt;
    }

    public DbSet<Country> Countries { get; set; }  
}  
argyle
  • 1,319
  • 2
  • 14
  • 28
Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • 1
    Don't fully understand your syntax, but the principal seems like the best way to me. The real question is if there's an even better way using EF 4.1. – Sander Rijken Oct 22 '11 at 19:08
  • @SanderRijken - What syntax don't you understand? It's pretty straight forward. DbContext implements the `IObjectContextAdapter` interface, that has a property called ObjectContext on it. You cast `this` to the adapter, then use it's ObjectContext property to set the event. – Erik Funkenbusch Oct 22 '11 at 19:42
  • 1
    `(event evt)`. I would probably expose the event as `public event EventHandler SavingChanges { add { ((IObjectContextAdapter)this).ObjectContext.SavingChanges += value; } remove { ((IObjectContextAdapater)this).ObjectContext.SavingChanges -= value; } }` – Sander Rijken Oct 22 '11 at 20:39
  • @SanderRijken - That's a possibility as well, it can be done any number of ways. It all depends on your preference. You really should remove and add the event in your add method, though, so the event won't get added twice. – Erik Funkenbusch Oct 22 '11 at 20:52
  • @MystereMan is it safe to call this "SetSavingChanges" method within the constructor of TestDb? – Stephen Holt Jul 16 '13 at 17:16
2

From what I can see on MSDN, DbContext wraps an instance of ObjectContext as a facade, not exposing this specific event.

However, DbContext does have a constructor overload that takes an ObjectContext - you can use this to pass in an ObjectContext and subscribe to the SavingChanges event on it.

using(ObjectContext context = new ObjectContext(myConnectionString))
{
  using(DbContext dbContext = new DbContext(context, true))
  {

  }
}
Oded
  • 489,969
  • 99
  • 883
  • 1,009
0

Another way may be, for example:

Public Class MainForm

  Private WithEvents myObjectContext As ObjectContext
  Private myDbContext As DbContext

...

  Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles Me.Load
    myDbContext = New DbContext
    myObjectContext = CType(myDbContext, IObjectContextAdapter).ObjectContext

...


  Private Sub ObjectContextSavingChanges(sender As Object, e As EventArgs) Handles myObjectContext.SavingChanges

    'Your code hear

  End Sub
Filippo Bottega
  • 109
  • 1
  • 6