在模型上使用DateTime.UtcNow始终在实体中创建迁移

问题描述 投票:2回答:2

我有一些具有CreatedDate和/或UpdatedDate属性的模型,在播种时,我将其设置为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)
c# entity-framework ef-code-first
2个回答
0
投票

与HasData一起使用,EF会将日期解析为新的日期。

如果我是你,我将通过固定日期使用可预测和可复制的种子。

或者如果您确实需要使用Now,则可以尝试manual migration并事先检查您的表种子是否已使用某些自定义逻辑运行。


0
投票

每次运行seed方法时,每次日期不同时,它将覆盖所有列。如果要防止这种覆盖输入数据,则需要检查数据库中是否还不存在它,然后运行它。或者,如果要防止更新某些字段,请覆盖SaveChanges()中的DbContext方法。

示例:-

1。如果您不想更新,请输入数据-

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。如果要防止更新某些字段(此过程适用于当前DbContext中任何位置的任何实体]->

属性-

[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; }
}

种子-

    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
    }

(已测试)

© www.soinside.com 2019 - 2024. All rights reserved.