All of our database tables have UpdateUserID and UpdateTS. I'd like to have this set if my entity has changes. Is there a way I can have this update on the spot conditionally?
If I manually set UpdateTS in code, then it will say that my entity has changed and will always update the object.
The TimeStamp attribute is used to specify that a property should take part in concurrency management. The TimeStamp attribute is only valid if applied to a property that is a byte array. How this is implemented is dependent on the current database provider. In SQL Server, this will map to a rowversion type.
BasketID == teacherGuid && b. Created == todaysDate) . ToList(); Otherwise you get today's date first.
IEntityTypeConfiguration<TEntity> InterfaceAllows configuration for an entity type to be factored into a separate class, rather than in-line in OnModelCreating(ModelBuilder).
The DbContext class has a method called OnModelCreating that takes an instance of ModelBuilder as a parameter. This method is called by the framework when your context is first created to build the model and its mappings in memory.
I couldn't get the solution proposed by @eric-j to work, it only set the dates when creating a new object but not when updating.
I found this solution and modified it to look similar. Have tried out it, and it works like a charm.
public override int SaveChanges()
{
var now = DateTime.UtcNow;
var entries = ChangeTracker
.Entries()
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);
foreach (var entry in entries)
{
if (entry.Entity is IHasLastModified lastModified)
{
lastModified.LastModified = now;
if (entry.State == EntityState.Added)
{
lastModified.CreatedDate = now;
}
}
}
return base.SaveChanges();
}
Here's an implementation of the other two ideas, with the following considerations
EntityState.Unmodified
, and the last modified timestamp will not be updated.EntityState.Added
)The Code
public interface IHasLastModified
{
DateTime? LastModified { get; set; }
}
public class MyClass : IHasLastModified
{
public virtual int Id { get; set; }
public virtual string SomeOtherProperty { get; set; }
public virtual DateTime? LastModified { get; set; }
}
public class MyContext : DbContext
{
public override int SaveChanges()
{
DateTime now = DateTime.UtcNow;
foreach (ObjectStateEntry entry in (this as IObjectContextAdapter).ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
{
if (!entry.IsRelationship)
{
IHasLastModified lastModified = entry.Entity as IHasLastModified;
if (lastModified != null)
lastModified.LastModified = now;
}
}
return base.SaveChanges();
}
I call this extension method before calling context.SaveChanges()
:
public static void SetLastModified(this ObjectContext context, DateTime dateTime)
{
DateTime now = DateTime.UtcNow;
foreach (ObjectStateEntry entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))
{
if (!entry.IsRelationship)
{
IHasLastModified lastModified = entry.Entity as IHasLastModified;
if (lastModified != null)
lastModified.LastModified = now;
}
}
}
I can easily call this code, because I've wrapper the ObjectContext in a repository class. If you're using it bare, you can hook up the ObjectContext.SavingChanges
event to do something similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With