Override SaveChanges in Entity Framework 5

Using C #, I have generated my DB model using "Generate from Database". The POCO classes and context are created using T4 templates. everything is working fine and the application can edit, insert, etc., but I cannot override the SaveChanges method in the object class. I need to do this to add buisiness logic. Here is the context class:

//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated from a template.
//
//    Manual changes to this file may cause unexpected behavior in your application.
//    Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace WebApplication1
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;

   public partial class IInvoiceEntities2 : DbContext
   {
        public IInvoiceEntities2 ()
            : base("name=IInvoiceEntities2 ")
        {
        }        


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }






    public DbSet<Company> Companies { get; set; }
    public DbSet<CompanyDetail> CompanyDetails { get; set; }
    public DbSet<CompanyVersion> CompanyVersions { get; set; }
    public DbSet<CustomerDetail> CustomerDetails { get; set; }
    }
}

      

Any ideas why my SaveChanges method doesn't hit when I set a breakpoint in it and edit an entity?

Update:

Now I override the ValidateEntity method in my context class as well as SaveChanges, but when I edit the entity and set a breakpoint in SaveChanges or ValidateEntity, none of the methods are called (see code above)

Update 2:

Now I have created an incomplete class in the App_Code folder for SaveChanges and ValidateEntity, but these methods still fail:

namespace WebApplication1
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;

public partial class IInvoiceEntities2 : DbContext
{
    public IInvoiceEntities2 ()
        : base("name=IInvoiceEntities2 ")
    {
    }


    public override int SaveChanges()
    {
        return base.SaveChanges();
    }




protected override DbEntityValidationResult ValidateEntity(
System.Data.Entity.Infrastructure.DbEntityEntry entityEntry,
IDictionary<object, object> items)
{
  // do stuff

    if (result.ValidationErrors.Count > 0)
    {
        return result;
    }
    else
    {
        return base.ValidateEntity(entityEntry, items);
    }
}





}

      

}

+3


source to share


3 answers


I am facing a serious solution to this problem as I was unable to override SaveChanges (). Instead, I am implementing the OnUpdating event for the EntityDataSource:

<asp:EntityDataSource ID="DetailsDataSource" runat="server" EnableUpdate="true"     
OnUpdating="DetailsDataSource_Updating" />

      

Then I have this method in my code, behind which I can perform server side validation:



protected void DetailsDataSource_Updating(object sender, EntityDataSourceChangingEventArgs e)
    {
        Country c = (Country) e.Entity;
        if (c.CountryName != "North pole")
            e.Cancel = true;
    }

      

I would like to override the save changes, but this will need to be done now. Thanks everyone for your help.

+1


source


you can use this partial class style if you want to override save changes, it should be noted that methods here are not usually called an indicator that the partial class does not match the actual class, namespace checks, etc.



public partial class MyEntities : DbContext
{
    public override int SaveChanges()
    {
        try
        {
            SavingChanges();
            return base.SaveChanges();
        }
        catch (Exception exception)
        {
            //handle errors here
        }
    }

    private void SavingChanges()
    {
        using (var OC = new MyEntities())
        {
            var objects = this.ChangeTracker.Entries()
                .Where(p => p.State == EntityState.Added || 
                    p.State == EntityState.Deleted || 
                    p.State == EntityState.Modified);

            // handle auditing
            AuditingHelperUtility.ProcessAuditFields(
                objects.Where(p => p.State == EntityState.Added));
            AuditingHelperUtility.ProcessAuditFields(
                objects.Where(p => p.State == EntityState.Modified), InsertMode: false);

            // Inserted objects
            foreach (DbEntityEntry entry in objects
                .Where(p => p.State == EntityState.Added))
            {
                if (entry.Entity != null)
                {
                    // insert code 
                }
            }

            // Updated objects
            foreach (DbEntityEntry entry in objects
                .Where(p => p.State == EntityState.Modified))
            {
                if (entry.Entity != null)
                {
                    // update code 
                }
            }

            // Delete objects
            foreach (DbEntityEntry entry in objects
                .Where(p => p.State == EntityState.Deleted))
            {
                if (entry.Entity != null)
                {
                    // delete code 
                }
            }
        }
    }
}

      

+4


source


NOTE. I only tested this in EF6, not EF5

The way to do this, which covers all scenarios (including EntityDataSource

), is to add an event handler for the SavingChanges event on the underlying ObjectContext. This can be done from the DbContext constructor:

 var objCx = (this as IObjectContextAdapter).ObjectContext;
 objCx.SavingChanges += (s, e) => { .... }

      

0


source







All Articles