【问题标题】:Entity Framework Core - CreatedTime Got Null When UpdateEntity Framework Core - CreatedTime 更新时为空
【发布时间】:2018-04-07 13:27:33
【问题描述】:

我希望 CreatedModified 字段 Automatically 使用 Entity Framework Core。我在here 中找到了解决方案并遵循了该解决方案。

添加数据效果很好-

但是如果我尝试更新数据(更新时间是完美的,但创建时间为空),那么我会遇到这样的问题-

所以,创建属性丢失了(设置为 Null

我的BaseEntity类是这样的-

public class BaseEntity
{
    [Key]
    public long Id { get; set; }

    [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss.fff}", ApplyFormatInEditMode = true)]
    public DateTime? CreatedTime { get; set; }
    public long CreatorUserId { get; set; }
    //public string CreatorIPAddress { get; set; }

    [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss.fff}", ApplyFormatInEditMode = true)]
    public DateTime? LastModifiedTime { get; set; }
    public long LastModifireUserId { get; set; }
    //public string LastModifireIPAddress { get; set; }
}

DbContext类是这样的-

public class ApplicationDbContext : DbContext
{
    //List all tables here
    public DbSet<Advertisement> Advertisements { get; set; }
    public DbSet<Address> Addresses { get; set; }
    public DbSet<Country> Countries { get; set; }
    public DbSet<EducationResult> EducationResults { get; set; }
    public DbSet<Experience> Experiences { get; set; }
    public DbSet<JobCircular> JobCirculars { get; set; }
    public DbSet<Language> Languages { get; set; }
    public DbSet<Reference> References { get; set; }
    public DbSet<Research> Researches { get; set; }
    public DbSet<ResearchDegree> ResearchDegrees { get; set; }
    public DbSet<TeacherApplication> TeacherApplications { get; set; }
    public DbSet<Training> Trainings { get; set; }

    //Configure Database Settings
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        //Configuration.GetConnectionString("DefaultConnection");
        optionsBuilder.UseSqlite("Filename=./applicationDB.db");
    }

    public override int SaveChanges()
    {
        AddTimestamps();
        return base.SaveChanges();
    }

    public override int SaveChanges(bool acceptAllChangesOnSuccess)
    {
        AddTimestamps();
        return base.SaveChanges(acceptAllChangesOnSuccess);
    }

    public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
    {
        AddTimestamps();
        return base.SaveChangesAsync(cancellationToken);
    }

    public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
    {
        AddTimestamps();
        return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
    }

    private void AddTimestamps()
    {
        var entities = ChangeTracker.Entries().Where(x => x.Entity is BaseEntity && (x.State == EntityState.Added || x.State == EntityState.Modified));

        /*
        var currentUsername = !string.IsNullOrEmpty(System.Web.HttpContext.Current?.User?.Identity?.Id)
            ? HttpContext.Current.User.Identity.Id
            : -1;   //-1 for Anonimous
        */
        long currentUserId = -1;    //-1 for Anonimous

        foreach (var entity in entities)
        {
            if (entity.State == EntityState.Added)
            {
                ((BaseEntity)entity.Entity).CreatedTime = DateTime.UtcNow;
                ((BaseEntity)entity.Entity).CreatorUserId = currentUserId;
                //((BaseEntity)entity.Entity).CreatorIPAddress = HttpContext.Connection.RemoteIpAddress.ToString();
            }
            else
            {
                ((BaseEntity)entity.Entity).CreatedTime = ((BaseEntity)entity.Entity).CreatedTime;
                ((BaseEntity)entity.Entity).CreatorUserId = ((BaseEntity)entity.Entity).CreatorUserId;
                //((BaseEntity)entity.Entity).CreatorIPAddress = ((BaseEntity)entity.Entity).CreatorIPAddress;
            }

            ((BaseEntity)entity.Entity).LastModifiedTime = DateTime.UtcNow;
            ((BaseEntity)entity.Entity).LastModifireUserId = currentUserId;
            //((BaseEntity)entity.Entity).LastModifireIPAddress = HttpContext.Connection.RemoteIpAddress.ToString();
        }
    }

    public DbSet<ApplicationManagement.DbModel.Office> Office { get; set; }
}

有人可以帮忙吗?

【问题讨论】:

  • 我使用实体模型作为视图模型。
  • FWIW,你只需要这样的东西来自动更新修改后的日期时间,创建可以更好地处理必须简单地使用默认值:public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
  • 请发布您如何查询和更新记录。上面的代码没有显示任何错误。
  • 好的,添加它们

标签: c# asp.net entity-framework asp.net-core entity-framework-core


【解决方案1】:

造成这种情况的唯一方法是使用实​​体模型作为视图模型。因此,您从表单或通过 API 调用发布实体,其中设置了几个属性,但不是 CreatedTimeCreatorUserId,导致它们获得默认值 null

然后您将这些空值分配给加载的实体,覆盖它们。

您可以通过使用视图模型并将适当的属性映射到加载的实体来防止这种情况:

// somewhere in a controller
public void UpdatePerson(UpdatePersonViewModel model)
{
    var entity = Get(model.Id);

    entity.Name = model.Name;

    Save(entity);
}

或者对实体而不是视图模型做同样的事情,我不推荐这样做。

【讨论】:

    【解决方案2】:

    逻辑上,对于修改状态,创建时间将保持原始创建时间。下面是从数据库中获取 originalValue 的脚本

    ((BaseEntity)entity.Entity).CreatedTime = entity.Property("CreatedTime").OriginalValue;
    

    【讨论】:

      【解决方案3】:

      你真的需要这段代码吗?

      else
      {
          ((BaseEntity)entity.Entity).CreatedTime = ((BaseEntity)entity.Entity).CreatedTime;
          ((BaseEntity)entity.Entity).CreatorUserId = ((BaseEntity)entity.Entity).CreatorUserId;
          //((BaseEntity)entity.Entity).CreatorIPAddress = ((BaseEntity)entity.Entity).CreatorIPAddress;
      }
      

      【讨论】:

      • 我已经尝试过了,但没有用 :( 所以,我删除了它们。这是你的答案吗?
      • 该代码无关紧要。我认为您不必在创建时再次设置该属性。
      猜你喜欢
      • 2020-04-28
      • 1970-01-01
      • 2020-06-06
      • 2022-08-02
      • 2017-09-17
      • 2017-02-11
      • 1970-01-01
      • 2020-12-06
      • 2020-02-06
      相关资源
      最近更新 更多