C# 如何在保存的实体及其子属性上使用实体框架自动设置CreatedOn字段
每当我调用C# 如何在保存的实体及其子属性上使用实体框架自动设置CreatedOn字段,c#,entity-framework,inheritance,entity-framework-6,C#,Entity Framework,Inheritance,Entity Framework 6,每当我调用databaseContext.SaveChanges(),在实体框架保存数据之前,我需要所有对象及其子类在CreatedOn字段中填充DateTime.Now() 详细信息:我有一个BaseEntity类,所有实体都从该类继承: public class BaseEntity { [Key] public virtual Guid Id{ get; set; } public DateTime CreatedOn { get; se
databaseContext.SaveChanges()
,在实体框架保存数据之前,我需要所有对象及其子类在CreatedOn
字段中填充DateTime.Now()
详细信息:我有一个BaseEntity
类,所有实体都从该类继承:
public class BaseEntity
{
[Key]
public virtual Guid Id{ get; set; }
public DateTime CreatedOn { get; set; }
}
每当保存从上面的BaseEntity
继承的实体时,就会分配CreatedOn
属性DateTime.Now
以下是执行此操作的基本存储库:
public abstract class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : BaseEntity
{
....
public virtual bool SaveChanges(TEntity entity)
{
if (entity.CreatedOn == DateTime.MinValue)
entity.CreatedOn = DateTime.Now;
else
entity.ModifiedOn = DateTime.Now;
return _databaseContext.SaveChanges() > 0;
}
}
确保为子
user.Role
以及user.Profile
对象(这两个类也从BaseEntity
继承)分配CreatedOn
日期的最佳方法是什么?我曾想过使用反射来检查CreatedOn
字段的子对象属性,但所有的循环感觉都不对。有更好的方法吗?基本上,您应该在自己的DB上下文类中重写SaveChanges
方法,并使用EF change tracker获取所有新创建的对象,然后相应地设置它们的CreatedOn
字段
大致如下:
public class DbContextBase : DbContext
{
public override int SaveChanges()
{
DateTime currentDateTime = DateTime.Now;
// get all the entities in the change tracker - this could be optimized
// to fetch only the entities with "State == added" if that's the only
// case you want to handle
IEnumerable<DbEntityEntry<BaseEntity>> entities = ChangeTracker.Entries<BaseEntity>();
// handle newly added entities
foreach (DbEntityEntry<BaseEntity> entity in entities.Where(e => (e.State == EntityState.Added))
{
// set the CreatedOn field to the current date&time
entity.Entity.CreatedOn = currentDateTime;
}
// to the actual saving of the data
return base.SaveChanges();
}
}
公共类DbContextBase:DbContext
{
公共覆盖int SaveChanges()
{
DateTime currentDateTime=DateTime.Now;
//获取更改跟踪器中的所有实体-这可以优化
//仅获取“State==added”的实体(如果这是唯一的
//你想处理的案子
IEnumerable entities=ChangeTracker.Entries();
//处理新添加的实体
foreach(entities.Where中的DbEntityEntry实体(e=>(e.State==EntityState.Added))
{
//将CreatedOn字段设置为当前日期和时间
entity.entity.CreatedOn=currentDateTime;
}
//到数据的实际保存
返回base.SaveChanges();
}
}
当然,您可以在这方面进行改进:
- 还可以使用
e.State==EntityState.Modified处理实体,并在本例中设置
字段ModifiedOn
- 添加一些自定义异常处理以处理常见问题案例
- 更重要的是,天空和你的想象力是极限
ChangeTracker.Entries()
替换为databaseContext.ChangeTracker.Entries()
然后它像一个符咒一样发挥了作用。我非常感谢。谢谢。也许可以更新你的答案,我会接受它作为解决方案。@InspiredBy:因为这个方法是在DbContext
子类上的,所以你应该能够使用我提供的原样代码-我已经使用了很多个月了。我不太确定你为什么需要添加数据baseContext.ChangeTracker
…被接受,因为这在技术上是正确的解决方案。希望这些评论能对后代有所帮助。
public class DbContextBase : DbContext
{
public override int SaveChanges()
{
DateTime currentDateTime = DateTime.Now;
// get all the entities in the change tracker - this could be optimized
// to fetch only the entities with "State == added" if that's the only
// case you want to handle
IEnumerable<DbEntityEntry<BaseEntity>> entities = ChangeTracker.Entries<BaseEntity>();
// handle newly added entities
foreach (DbEntityEntry<BaseEntity> entity in entities.Where(e => (e.State == EntityState.Added))
{
// set the CreatedOn field to the current date&time
entity.Entity.CreatedOn = currentDateTime;
}
// to the actual saving of the data
return base.SaveChanges();
}
}