如何在保存的实体及其 child 属性上使用 Entity Framework 自动设置 CreatedOn 字段
How to automatically set CreatedOn fields with Entity Framework on saved entity and its child properties
每当我调用 databaseContext.SaveChanges()
时,在 Entity Framework 保存数据之前,我需要所有 object 及其 child class 拥有CreatedOn
字段填充了 DateTime.Now()
.
详细信息:我有一个 BaseEntity
class 所有实体都继承自:
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;
}
}
这很好用,但问题是只有 object 本身 CreatedOn
属性 得到更新。任何 child class 可能 不会 更新。
如何更改 SaveChanges()
方法中的逻辑以更新所有 child class 并设置它们的 CreatedOn
日期?
我将提供一个示例来更清楚地说明这一点:假设下面的 User
object 实例添加到 dbContext
中,并带有新的 Profile
,以及分配新的 Role
class 个实例,然后调用 SaveChanges()
:
public class User: BaseEntity
{
[Key]
public virtual Guid Id { get; set; }
public UserRole Role { get; set; }
public ProfileDetails Profile { get; set; }
public DateTime CreatedOn { get; set; }
public Guid CreatedBy { get; set; }
}
确保为 child user.Role
以及 user.Profile
object 分配 CreatedOn
日期的最佳方法是什么(classes也继承自BaseEntity
)?我想过使用反射来检查 CreatedOn
字段的 child object 属性,但所有循环都感觉不对。有没有更好的方法?
基本上,您应该在自己的数据库上下文 class 中覆盖 SaveChanges
方法并使用 EF 更改跟踪器获取所有新创建的对象,然后设置它们的 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();
}
}
当然你可以改进这个:
- 还使用
e.State == EntityState.Modified
处理实体并在本例中设置 ModifiedOn
字段
- 添加一些自定义异常处理来处理常见问题
- 更多 - 天空和您的想象力是无限的!
每当我调用 databaseContext.SaveChanges()
时,在 Entity Framework 保存数据之前,我需要所有 object 及其 child class 拥有CreatedOn
字段填充了 DateTime.Now()
.
详细信息:我有一个 BaseEntity
class 所有实体都继承自:
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;
}
}
这很好用,但问题是只有 object 本身 CreatedOn
属性 得到更新。任何 child class 可能 不会 更新。
如何更改 SaveChanges()
方法中的逻辑以更新所有 child class 并设置它们的 CreatedOn
日期?
我将提供一个示例来更清楚地说明这一点:假设下面的 User
object 实例添加到 dbContext
中,并带有新的 Profile
,以及分配新的 Role
class 个实例,然后调用 SaveChanges()
:
public class User: BaseEntity
{
[Key]
public virtual Guid Id { get; set; }
public UserRole Role { get; set; }
public ProfileDetails Profile { get; set; }
public DateTime CreatedOn { get; set; }
public Guid CreatedBy { get; set; }
}
确保为 child user.Role
以及 user.Profile
object 分配 CreatedOn
日期的最佳方法是什么(classes也继承自BaseEntity
)?我想过使用反射来检查 CreatedOn
字段的 child object 属性,但所有循环都感觉不对。有没有更好的方法?
基本上,您应该在自己的数据库上下文 class 中覆盖 SaveChanges
方法并使用 EF 更改跟踪器获取所有新创建的对象,然后设置它们的 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();
}
}
当然你可以改进这个:
- 还使用
e.State == EntityState.Modified
处理实体并在本例中设置ModifiedOn
字段 - 添加一些自定义异常处理来处理常见问题
- 更多 - 天空和您的想象力是无限的!