Best way to override SaveChanges()

后端 未结 3 1139
-上瘾入骨i
-上瘾入骨i 2020-12-16 16:43

We have worked on a project for 1 month and there are 6 entities without any relationship with other entities. They are all simple entities.

We have created 6 diffe

相关标签:
3条回答
  • 2020-12-16 17:05

    To 'override' SaveChanges without needing to create all that extra code, I wrapped it in its own extension method. i.e.

    public static int SaveChangesWrapped(this MyDbContext db)
    {
        // do other things
    
        return db.SaveChanges();
    }
    

    or async...

    public static Task<int> SaveChangesAsyncWrapped(this MyDbContext db)
    {
        // do other things
    
        return await db.SaveChangesAsync();
    }
    

    You can tweak it however you need, i.e. add other parameters, make it generic, etc. I may be missing something but this was enough for me to 'override' SaveChanges and cut down a whole lot of repeated code.

    Then anywhere in your code when you want to save, it's just:

    db.SaveChangesWrapped();
    
    //or
    
    await db.SaveChangedAsyncWrapped();
    
    0 讨论(0)
  • 2020-12-16 17:09

    This code will be better with :

        var added = this.ChangeTracker.Entries()
                .Where(t => t.Entity is ITrack && t.State == EntityState.Added)
                .Select(t => t.Entity)
                .ToArray();
    

    The same for modified :

        var modified = this.ChangeTracker.Entries()
                .Where(t => t.Entity is ITrack && t.State == EntityState.Modified)
                .Select(t => t.Entity)
                .ToArray();
    

    And remove if conditions in foreach loop...

    0 讨论(0)
  • 2020-12-16 17:17

    you can do the following

    1- create an Interface in your application that all the classes that has the following properties will implement this interface: Id, CreatedDate,CreatedBy, ModifiedDate,ModifiedBy

    public interface ITrack
    {
          int Id{get; set;}
          int CreatedBy{get; set;}
          DateTime CreatedDate{get; set;}
          int? ModifiedBy{get; set;} // int? because at first add, there is no modification
          DateTime? ModifiedBy {get; set;}
    }
    

    Best practices Define the CreatedBy and ModifiedBy as string which will be good for performance and maintenance

    2- Add a class TrackableEntry which implements the interface ITrack

    public abstract class TrackableEntry : ITrack
    {
          public int Id{get; set;}
          public int CreatedBy{get; set;}
          public DateTime CreatedDate{get; set;}
          public int? ModifiedBy{get; set;} 
          public DateTime? ModifiedBy {get; set;}
    }
    

    3- remove the properties mentioned in the interface from all of your classes and let these classes to implement directly from TrackableEntry

    public class A: TrackableEntry
    {
        //public int Id{get; set;}
        //public int CreatedBy{get; set;}
        //public DateTime CreatedDate{get; set;}
        //public int? ModifiedBy{get; set;}
        //public DateTime? ModifiedBy {get; set;}
    }
    

    4- In your DbContext file override your SaveChanges and add property UserId or UserName if you followed the *Best practices* part

    public int UserId{get; set;}
    
    public override int SaveChanges()
    {
        this.ChangeTracker.DetectChanges();
        var added = this.ChangeTracker.Entries()
                    .Where(t => t.State == EntityState.Added)
                    .Select(t => t.Entity)
                    .ToArray();
    
        foreach (var entity in added)
        {
            if (entity is ITrack)
            {
                var track = entity as ITrack;
                track.CreatedDate = DateTime.Now;
                track.CreatedBy = UserId;
            }
        }
    
        var modified = this.ChangeTracker.Entries()
                    .Where(t => t.State == EntityState.Modified)
                    .Select(t => t.Entity)
                    .ToArray();
    
        foreach (var entity in modified)
        {
            if (entity is ITrack)
            {
                var track = entity as ITrack;
                track.ModifiedDate = DateTime.Now;
                track.ModifiedBy = UserId;
            }
        }
        return base.SaveChanges();
    }
    

    finally in your forms when you want to call SaveChanges method, ensure you set the UserId or UserName value

    var entities=new Entities(); // assuming that your DbContext file called Entities
    // code for adding or deletion or modification here
    entities.As.Add(new A(){...});
    
    // ....
    
    entities.UserId=MyUser;
    entities.SaveChanges();
    

    hope this will help you

    0 讨论(0)
提交回复
热议问题