【问题标题】:How to Add TimeStamps in Entity Framework如何在实体框架中添加时间戳
【发布时间】:2020-12-24 19:25:39
【问题描述】:

从使用 PHP 开始,使用 Timestamps 相当直接,但使用 Entity Framework,这有点令人头疼。

【问题讨论】:

    标签: c# sql-server entity-framework entity-framework-core timestamp


    【解决方案1】:

    这是一个对我有用的解决方案。 首先,我有一个所有实体都继承自的 Baseentity:

    public abstract class DbEntity
    {
    
        [Column("created_at")]
        public DateTime CreatedAt { get; set; } = DateTime.Now;
        
        [Column("updated_at")]
        public DateTime UpdatedAt { get; set; } = DateTime.Now;
    }
    

    然后我为UpdateMethod添加了一个扩展方法:

    public static class DbSetExtension
    {
        public static EntityEntry<TEntity> UpdateCustom<TEntity>(this DbSet<TEntity> dbSet, TEntity dbEntity)
            where TEntity : class
        {
    
            dbEntity.GetType().GetProperty("UpdatedAt")?.SetValue (dbEntity, DateTime.Now, null);
                
            return dbSet.Update(dbEntity);
        }
    }
    

    这对我来说很好。我会感谢其他人如何处理这种情况的反馈。

    P.S:即使在为列设置默认 SQL 之后,[DatabaseGenerated(DatabaseGeneratedOption.Computed)] 方法对我也不起作用。

    【讨论】:

      【解决方案2】:

      我很确定您正在使用时间戳来处理一些并发冲突。 在 Entity Framework (Core) 中实际上有两种方法

      • 使用并发令牌将实体类中的特定属性/列标记为一个以检查并发冲突。
      • 使用 timestamp,它将整个实体类/行标记为一个以检查并发冲突。

      对属性设置并发检查

      您可以使用实体类上的数据注释来配置并发令牌。

      public class BookEntity
      {
          public int BookId {get; set;}
          public string Title {get; set;}
         
          // This tells EF that this property is a concurrency token,
          // which means EF will check it hasn't changed when you update it
          [ConcurrencyCheck]
          public DateTime PublishedOn {get; set;}
      
          // Other properties follow...
      }
      

      也可以使用fluent API配置并发检查

      protected override void OnModelCreating(ModelBuilder builder)
      {
          builder.Entity<BookEntity>()
              .Property(p=> p.PublishedOn)
              .IsConcurrencyToken();
      
          // ...other configurations follow...
      }
      

      为属性设置时间戳

      您可以使用实体类上的数据注释来配置时间戳。

      public class BookEntity
      {
          public int BookId {get; set;}
          public string Title {get; set;}
         
          // This tells EF to mark ChangeCheck property as a timestamp,
          // This causes EF to check this when updating to see if this has changed
          [Timestamp]
          public byte[] ChangeCheck {get; set;}
      
          // Other properties follow...
      }
      

      使用 Fluent API 配置时间戳

      protected override void OnModelCreating(ModelBuilder builder)
      {
          // Value of ChangeCheck will be changed each time the row 
          // created/updated
          builder.Entity<BookEntity>()
              .Property(p=> p.ChangeCheck)
              .IsRowVersion;
      
          // ...other configurations follow...
      }
      

      这两种配置都会在表中创建一个列,只要对该表进行 INSERT 或 UPDATE,数据库服务器就会自动更改该列。

      设置计算/用户友好的时间戳

      这只能通过 Fluent API 完成

      public class BookEntity
      {
          public int BookId {get; set;}
          public string Title {get; set;}
         
          // Column you set up as computed
          // You give it a private setter, as its a read-only property
          public DateTime DateModified {get; private set;}
      
          // Other properties follow...
      }
      

      然后您通过 Fluent API 配置列。

      protected override void OnModelCreating(ModelBuilder builder)
      {
          builder.Entity<BookEntity>()
              .Property(p=> p.DateModified)
              .HasComputedColumnSql("getutcdate()")
              .ValueGeneratedOnAddOrUpdate();
      
          // ...other configurations follow...
      }
      

      .HasComputedColumnSql("getutcdate()") 将告诉 EF 计算列的值;在这种情况下,要获取当前的 UTC 日期时间,然后 .ValueGeneratedOnAddOrUpdate(),将让 EF 知道该列已计算,因此应在进行任何更新时更新该列。

      【讨论】:

      • 我正在使用时间戳为最终用户提供更具可读性的数据,而在 RowVerson 上使用[Timestamp] 可以实现并发,最终用户不会看到它实际更新的时间
      • 确实如此。我添加了一个涉及手动配置时间戳的更新。我希望它有所帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多