Best way to override SaveChanges ()
We have been working on the project for 1 month and there are 6 properties without any relationship with other properties. They are all simple entities.
We have created 6 different classes for operations on each object. The SaveOrUpdateEntity () class methods are almost the same as you might think. It's something like this:
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 the SaveOrUpdateEntity () method is shorter and more general by overriding the SaveChanges () method. According to other questions, articles and posts about overriding the SaveChanges () method, implementing an interface that stores the state of objects is a good solution, but I'm also wondering what other solutions are.
As I am a newbie, all answers would be much appreciated.
Thank.
source to share
you can do the following
1- create an interface in your application so that all classes that have the following properties 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;}
}
Recommendations Determine
CreatedBy
andModifiedBy
Howstring
That Will Be Good for Performance and Maintenance
2- Add a class TrackableEntry
that implements the interfaceITrack
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 properties mentioned in interface from all of your classes and let those classes 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 file DbContext
override 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 a method SaveChanges
make sure you set a value UserId
orUserName
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 helps you
source to share