Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
178 views
in Technique[技术] by (71.8m points)

c# - Best way to override SaveChanges()

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 different classes for operations on each entity. SaveOrUpdateEntity() methods of classes are almost same as you think. It is something like that:

public static ErrorType SaveOrUpdateEntity(Entity entity, int userID)
{
    try
    {
        using (DataEntities ctx = new DataEntities())
        {
            if (entity != null)
            {
                if (entity.entityID == 0)
                {
                    entity.CreateDate = DateTime.Now;
                    entity.CreatedBy = userID;

                    ctx.Entry(entity).State = EntityState.Added;
                }
                else
                {
                    entity.ModifyDate = DateTime.Now;
                    entity.ModifiedBy = userID;

                    ctx.Entry(entity).State = EntityState.Modified;
                }
            }

            ctx.SaveChanges();
        }

        return ErrorType.NoError;
    }
    catch (Exception ex)
    {
        return ErrorType.SaveError;
    }
}

It would be very helpful, if SaveOrUpdateEntity() method is shorter and more generic by overriding SaveChanges() method. According to other questions, articles, and posts about overriding SaveChanges() method, implementing interface that stores state of entities is a good solution but I am also wondering other solutions.

Because I am newbie, all answers would be very appreciated.

Thank you.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...