I've got a few models that have a CreatedDate and/or UpdatedDate property, and in my seeding I'm setting those to DateTime.UtcNow.
new TestModel()
{
Id = 1,
Name = name,
CreatedDateUtc = DateTime.UtcNow,
CreatedBy = "Seed",
UpdatedDateUtc = DateTime.UtcNow,
UpdatedBy = "Seed",
DeletedDateUtc = null,
DeletedBy = null,
},
Now, even though the seed data is in the database, EF thinks that it needs to update them with a new date. Is that the expected behavior? Am I stuck specifying a date for those columns? Something like this:
DateTime(2020, 01, 01, 12, 00, 00, DateTimeKind.Utc)
Every time when the seed method is running, it will overwrites all of the columns and every time the dates are different. If you want to prevent this overwrite enter data, then you need to check if it's not already exist in your db then run it. Or override the SaveChanges()
method in the DbContext
, if want to prevent update some fields.
Example:-
1.If you don't want to update enter data then--
protected override void Seed(ApplicationDbContext context)
{
if (!context.TestModels.Any(u => u.Id== 1))
{
context.TestModels.AddOrUpdate(p => p.Id, new TestModel()
{
Id = 1,
Name = "Test",
CreatedDateUtc = DateTime.UtcNow,
CreatedBy = "Seed",
UpdatedDateUtc = DateTime.UtcNow,
UpdatedBy = "Seed",
DeletedDateUtc = null,
DeletedBy = null,
});
}
base.Seed(context);
}
2.If want to prevent update some fields(this process work for any entity from any where in the current DbContext)--
Attribute--
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public sealed class IgnoreUpdateAttribute : Attribute
{
}
Model--
public class TestModel
{
public int Id { get; set; }
public string Name { get; set; }
[IgnoreUpdate]//for ignoring update
public DateTime CreatedDateUtc { get; set; }
[IgnoreUpdate]//for ignoring update
public string CreatedBy { get; set; }
public DateTime UpdatedDateUtc { get; set; }
public string UpdatedBy { get; set; }
public DateTime? DeletedDateUtc { get; set; }
public string DeletedBy { get; set; }
}
Seed--
protected override void Seed(ApplicationDbContext context)
{
context.TestModels.AddOrUpdate(p => p.Id, new TestModel()
{
Id = 1,
Name = "Test",
CreatedDateUtc = DateTime.UtcNow,
CreatedBy = "Seed",
UpdatedDateUtc = DateTime.UtcNow,
UpdatedBy = "Seed",
DeletedDateUtc = null,
DeletedBy = null,
});
base.Seed(context);
}
DbContext--
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public DbSet<TestModel> TestModels { get; set; }
//---DB Set
public override int SaveChanges()
{
var entities= ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).ToList();
foreach (var entry in entities)
{
var properties = typeof(TestModel).GetProperties()// get you model properties
.Where(property =>
property != null && Attribute.IsDefined(property, typeof(IgnoreUpdateAttribute)))//which has decorated as IgnoreUpdate
.Select(p => p.Name);
foreach (var property in properties)
{
entry.Property(property).IsModified = false;
}
}
return base.SaveChanges();
}
//--- Code
}
(Tested)
Seeding with HasData, EF will resolve the date to a new one ever time.
If I were you, I would use a predictable and reproducible seed by having a fixed date.
Or if you really need to use Now, you could try manual migration and checking beforehand if your table seed has already been run with some custom logic.
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