带有 EF Core 2.1 和 Sql Server 的时间戳?

cho*_*bo2 5 entity-framework ef-code-first ef-core-2.1

我想在我的大多数表上基本上都有一个“上次更新”列,以便我可以快速检查它上次更新的时间。

现在我只是放置一个日期时间,每次我在 C# 代码中执行操作时,我都会保存新的 DateTime 以更新该字段。当然,这会导致我忘记这样做。

我想要更自动化的东西。我真的不需要这个用于审计目的,所以它不需要太先进。

我试过

builder.Property(x => x.RowVersion).IsRowVersion();
Run Code Online (Sandbox Code Playgroud)

什么应该制作时间戳,但是当我查看数据库时,我看到0x00000000000007D1我认为它看起来更像日期时间。

编辑

 public class CompanyConfig : IEntityTypeConfiguration<Company>
    {
        public void Configure(EntityTypeBuilder<Company> builder)
        {
            builder.HasKey(x => x.Id);
            builder.Property(x => x.Id).ValueGeneratedOnAdd();
            builder.Property<DateTime>("LastUpdated");
        }
    }
Run Code Online (Sandbox Code Playgroud)

Iva*_*oev 5

假设您已经LastModified为您想要该功能的每个实体定义了一个影子属性,如您的示例

builder.Property<DateTime>("LastUpdated");
Run Code Online (Sandbox Code Playgroud)

问题是如何自动更新它。

David's answer中描述的技术已经过时。仍然可以覆盖SaveChanges(和SaveChangesAsync),但恕我直言,有一种更好的方法,在 EF Core 中自动填充创建和 LastModified 中显示。它是基于接口的方法,但可以轻松调整阴影属性(或任何属性 - 使用的方法适用于阴影和显式属性)。

快速回顾:从 v2.1 开始,EF Core 提供状态更改事件

New TrackedAnd StateChangedevents onChangeTracker可用于编写对实体进入DbContext或更改其状态做出反应的逻辑。

以下是如何利用它们。将以下内容添加到您的派生上下文类中:

void SubscribeStateChangeEvents()
{
    ChangeTracker.Tracked += OnEntityTracked;
    ChangeTracker.StateChanged += OnEntityStateChanged;
}

void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e)
{
    ProcessLastModified(e.Entry);
}

void OnEntityTracked(object sender, EntityTrackedEventArgs e)
{
    if (!e.FromQuery)
        ProcessLastModified(e.Entry);
}

void ProcessLastModified(EntityEntry entry)
{
    if (entry.State == EntityState.Modified || entry.State == EntityState.Added)
    {
        var property = entry.Metadata.FindProperty("LastModified");
        if (property != null && property.ClrType == typeof(DateTime))
            entry.CurrentValues[property] = DateTime.UtcNow;
    }
}
Run Code Online (Sandbox Code Playgroud)

并添加

SubscribeStateChangeEvents();
Run Code Online (Sandbox Code Playgroud)

到您的派生上下文构造函数。

就这样。一旦上下文订阅了这些事件,它就会在实体最初被跟踪或其状态发生变化时收到通知。您只有兴趣ModifiedAdded状态不会被物化查询触发(如果你不需要做Added,那么就排除从if状态)。然后DateTime LastModified使用 EF Core 元数据服务检查实体是否包含属性,如果是,只需使用当前日期/时间更新它。

  • 您可以使用 [EF.Property](https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.ef.property?view=efcore-2.1) 方法访问 LINQ to Entities 中的此类字段查询,这意味着您可以进行过滤、排序、`select` 等操作,例如 `db.Set&lt;Company&gt;().Where(e =&gt; EF.Property&lt;DateTime&gt;(e, "LastModified") &lt; someDate).OrderByDescending (e =&gt; EF.Property&lt;DateTime&gt;(e, "LastModified"))` 等。但如果你经常需要,添加显式属性会更好。好消息是,显式或影子,更改跟踪处理代码将是相同的。 (2认同)