EntityFramework核心2-ValueGeneratedOnAddOrUpdate

Muh*_*igo 4 c# entity-framework-core .net-core asp.net-core

我有一个场景,其中我的模型具有字段CreatedOn和UpdatedOn,并按照我在EF Core文档中找到的内容进行实现,如下所示

builder.Entity<Registro>(b =>
    {
        b.Property<DateTime>("CreatedOn")
            .IsRequired()
            .ValueGeneratedOnAdd()
            .HasDefaultValueSql("GETUTCDATE()");

        b.Property<DateTime>("UpdatedOn")
            .IsRequired()
            .ValueGeneratedOnAddOrUpdate()
            .HasDefaultValueSql("GETUTCDATE()"); ;
    });

public class Registro
{
    public Guid Id { get; set; }
    public string Nome { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

插入时,两个字段都保存了正确的值,但是更新并没有如我所料,UpdatedOn保留了保存值。它还遵循我如何进行实体更新

public void Put(Guid id, [FromBody]string value)
{
    var r = context.Registros.SingleOrDefault(x => x.Id == id);

    r.Nome = value;

    context.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

Dar*_*amb 6

为了使UpdatedOn时间戳自动更新,可以选择的一种方法是实现一个描述功能的接口并重载DbContexts SaveChanges方法。

public interface IUpdateable 
{ 
    DateTime UpdatedOn { get; set; }  
}

public class Registro : IUpdateable
{
    public Guid Id { get; set; }
    public string Nome { get; set; }
    public DateTime UpdatedOn { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的Context类中

public override int SaveChanges()
{
    var currentDateTime = DateTime.Now;
    var entries = ChangeTracker.Entries().ToList();

    // get a list of all Modified entries which implement the IUpdatable interface
    var updatedEntries = entries.Where(e => e.Entity is IUpdateable)
            .Where(e => e.State == EntityState.Modified)
            .ToList();

    updatedEntries.ForEach(e =>
    {
        ((IUpdateable)e.Entity).UpdatedOn = currentDateTime;
    });


    return base.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)