C# 实体框架核心-更新时CreatedTime为Null
我希望使用实体框架核心自动创建和修改字段。我在中找到了一个解决方案,并遵循了这一点 它非常适合添加数据- 但若我试图更新数据(更新时间是完美的,但创建时间为空),那个么我就会遇到这样的问题-C# 实体框架核心-更新时CreatedTime为Null,c#,asp.net,entity-framework,asp.net-core,entity-framework-core,C#,Asp.net,Entity Framework,Asp.net Core,Entity Framework Core,我希望使用实体框架核心自动创建和修改字段。我在中找到了一个解决方案,并遵循了这一点 它非常适合添加数据- 但若我试图更新数据(更新时间是完美的,但创建时间为空),那个么我就会遇到这样的问题- public class BaseEntity { [Key] public long Id { get; set; } [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm
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; }
}
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; }
}
因此,创建属性丢失(设置为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; }
}
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; }
}
而DbContext类是这样的-
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; }
}
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; }
}
公共类ApplicationDbContext:DbContext
{
//在此列出所有表格
公共数据库集播发{get;set;}
公共数据库集地址{get;set;}
公共数据库集国家{get;set;}
公共数据库集教育结果{get;set;}
公共数据库集{get;set;}
公共DbSet作业循环{get;set;}
公共数据库集语言{get;set;}
公共数据库集引用{get;set;}
公共数据库集{get;set;}
公共DbSet ResearchDegrees{get;set;}
公共DbSet教学应用程序{get;set;}
公共数据库集{get;set;}
//配置数据库设置
配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
{
//GetConnectionString(“DefaultConnection”);
optionsBuilder.UseSqlite(“文件名=./applicationDB.db”);
}
公共覆盖int SaveChanges()
{
AddTimestamps();
返回base.SaveChanges();
}
公共覆盖int SaveChanges(bool acceptAllChangesOnSuccess)
{
AddTimestamps();
返回base.SaveChanges(AcceptalChangesOnSuccess);
}
公共覆盖任务saveChangesSync(CancellationToken CancellationToken=默认值(CancellationToken))
{
AddTimestamps();
返回base.saveChangesSync(cancellationToken);
}
public override Task savechangesync(bool acceptillchangesonsuccess,CancellationToken CancellationToken=default(CancellationToken))
{
AddTimestamps();
return base.saveChangesSync(acceptAllChangesOnSuccess,cancellationToken);
}
私有void AddTimestamps()
{
var entities=ChangeTracker.Entries()。其中(x=>x.Entity为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表示一个动物
*/
长currentUserId=-1;//-1表示匿名
foreach(实体中的var实体)
{
if(entity.State==EntityState.Added)
{
((BaseEntity)entity.entity).CreatedTime=DateTime.UtcNow;
((BaseEntity)entity.entity).CreatorUserId=currentUserId;
//((BaseEntity)entity.entity.CreatorIPAddress=HttpContext.Connection.RemoteIpAddress.ToString();
}
其他的
{
((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();
}
}
公共数据库集办公室{get;set;}
}
有人能帮忙吗?造成这种情况的唯一方法是使用实体模型作为视图模型。因此,您从表单或通过设置了两个属性的API调用发布一个实体,而不是
CreatedTime
或CreatorUserId
,从而使它们获得默认值null
然后将这些空值指定给加载的实体,并覆盖它们
可以通过使用viewmodels并将适当的属性映射到加载的实体来防止这种情况:
// somewhere in a controller
public void UpdatePerson(UpdatePersonViewModel model)
{
var entity = Get(model.Id);
entity.Name = model.Name;
Save(entity);
}
或者对实体而不是viewmodel执行相同的操作,我不建议这样做。导致这种情况的唯一方法是将实体模型用作视图模型。因此,您从表单或通过设置了两个属性的API调用发布一个实体,而不是
CreatedTime
或CreatorUserId
,从而使它们获得默认值null
然后将这些空值指定给加载的实体,并覆盖它们
可以通过使用viewmodels并将适当的属性映射到加载的实体来防止这种情况:
// somewhere in a controller
public void UpdatePerson(UpdatePersonViewModel model)
{
var entity = Get(model.Id);
entity.Name = model.Name;
Save(entity);
}
或者对实体而不是viewmodel执行相同的操作,我不建议这样做。从逻辑上讲,对于修改状态,创建时间将保持原始创建时间。下面是获取原始值FOMDB的脚本
((BaseEntity)entity.Entity).CreatedTime = entity.Property("CreatedTime").OriginalValue;
从逻辑上讲,对于修改后的状态,创建时间将保持原始创建时间。下面是获取原始值FOMDB的脚本
((BaseEntity)entity.Entity).CreatedTime = entity.Property("CreatedTime").OriginalValue;
你真的需要这个代码吗
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;
}
您真的需要此代码吗
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;
}
我使用实体模型作为视图模型。FWIW,aut只需要这样的东西