1

I have an issue where I want to override SaveChanges() as I need to check some values being saved to the database and change them before they are saved.

I know I can override SaveChanges() in the DBContext:

var changeSet = ChangeTracker.Entries<Page>();
if (changeSet != null)
{
    foreach (var entry in changeSet)
    {
        switch (entry.State)
        {
            case System.Data.EntityState.Added:
                if (((Page)entry.Entity).Parent_PageID == -1)
                    ((Page)entry.Entity).Parent_PageID = null;
            break;
        }
    }
}

but this will get messy very quickly if I need to do this on multiple models.

How can I do this per model?

1 Answer 1

1

Answering my own question here as I didn't find any help for this so it might help someone else down the line. SO seemed the best place to share this.


Make sure you have a base model (or interface) of some kind with the following declaration:

public class BaseModel
{
    public virtual void OnSaveChanges<T>(T Obj)
    {

    }
}

Add the override in your derived model:

public class Page : BaseModel
{
    //property declarations

    public override void OnSaveChanges<T>(T Obj)
    {
        base.OnSaveChanges<T>(Obj);
        Page model = Obj as Page;

        //Do something with the object.
        if (model.Parent_PageID == -1)
            model.Parent_PageID = null;

    }
}

Add the following into your derived DBContext class:

public override int SaveChanges()
{
    foreach (var changeSet in ChangeTracker.Entries())
    {
        var type = Type.GetType(changeSet.Entity.GetType().ToString());
        if (type != null)
            BaseModel Obj = (BaseModel)Convert.ChangeType(changeSet.Entity, type);
            Obj.OnSaveChanges(changeSet.Entity);
        }
    }            
    return base.SaveChanges();
}

This will now call SaveChanges() for all your models that derive from BaseModel which allows you to make any last minute changes.

Note: Sometimes you could just use the getter or setter of the var but due to the issue I had with Foreign keys, I wasn't able to in this case.

This can be easily adapted to add AfterSave events etc.

HTH some one else.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for sharing, why would you choose BaseModel, not an interface
I had a base model in place for other things so I just put it in there but I agree an interface might be better here.
Your SaveChanges() is used more like a BeforeSave(). And it's not something we want as part of the model in most cases. And when we do, there's T4.
@HenkHolterman - I agree (and have renamed it locally since posting). It might have limited use but it helped in my instance.
Text Template Tools Tomething. Part of the templates for EF5 model-first and db-first.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.