在模型上使用 DateTime.UtcNow 总是在实体中创建迁移
Using DateTime.UtcNow on model always creates a migration in Entity
我有几个模型有创建日期 and/or 更新日期 属性,在我的播种中我将它们设置为 DateTime.UtcNow。
new TestModel()
{
Id = 1,
Name = name,
CreatedDateUtc = DateTime.UtcNow,
CreatedBy = "Seed",
UpdatedDateUtc = DateTime.UtcNow,
UpdatedBy = "Seed",
DeletedDateUtc = null,
DeletedBy = null,
},
现在,即使种子数据在数据库中,EF 认为它需要用新日期更新它们。这是预期的行为吗?我是否坚持为这些专栏指定日期?像这样:
DateTime(2020, 01, 01, 12, 00, 00, DateTimeKind.Utc)
使用 HasData 播种,EF 每次都会将日期解析为新日期。
如果我是你,我会使用谓词table 和具有固定日期的可重现种子。
或者如果您真的需要使用 Now,您可以尝试 manual migration 并事先检查您的 table 种子是否已经 运行 具有一些自定义逻辑。
每次种子方法为 运行ning 时,它都会覆盖所有列,并且每次日期都不同。如果你想防止这种覆盖输入数据,那么你需要检查它是否已经存在于你的数据库中然后 运行 它。或者覆盖 DbContext
中的 SaveChanges()
方法,如果想防止更新某些字段。
例子:-
1.If 那你不想更新输入数据--
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 想要防止更新某些字段(此过程适用于当前 DbContext 中任何位置的任何实体)--
属性--
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public sealed class IgnoreUpdateAttribute : Attribute
{
}
型号--
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; }
}
种子--
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
}
(已测试)
我有几个模型有创建日期 and/or 更新日期 属性,在我的播种中我将它们设置为 DateTime.UtcNow。
new TestModel()
{
Id = 1,
Name = name,
CreatedDateUtc = DateTime.UtcNow,
CreatedBy = "Seed",
UpdatedDateUtc = DateTime.UtcNow,
UpdatedBy = "Seed",
DeletedDateUtc = null,
DeletedBy = null,
},
现在,即使种子数据在数据库中,EF 认为它需要用新日期更新它们。这是预期的行为吗?我是否坚持为这些专栏指定日期?像这样:
DateTime(2020, 01, 01, 12, 00, 00, DateTimeKind.Utc)
使用 HasData 播种,EF 每次都会将日期解析为新日期。
如果我是你,我会使用谓词table 和具有固定日期的可重现种子。
或者如果您真的需要使用 Now,您可以尝试 manual migration 并事先检查您的 table 种子是否已经 运行 具有一些自定义逻辑。
每次种子方法为 运行ning 时,它都会覆盖所有列,并且每次日期都不同。如果你想防止这种覆盖输入数据,那么你需要检查它是否已经存在于你的数据库中然后 运行 它。或者覆盖 DbContext
中的 SaveChanges()
方法,如果想防止更新某些字段。
例子:-
1.If 那你不想更新输入数据--
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 想要防止更新某些字段(此过程适用于当前 DbContext 中任何位置的任何实体)--
属性--
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public sealed class IgnoreUpdateAttribute : Attribute
{
}
型号--
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; }
}
种子--
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
}
(已测试)