我正在做一个代码优先项目,我需要数据库来处理DateCreated和DateModified.
该应用程序运行在IIS上,并在开发计算机上的LocalDB上运行,并将在部署服务器上使用Server 2012和IIS7.5。
我有以下模式:
public class Person : IdentityUser {
[Required]
public string Name { get; set; }
public Date DateOfBirth { get; set; }
public string Address { get; set; }
[DatabaseGeneratedOption.Identity]
public Date DateCreated { get; set; }
[DatabaseGeneratedOption.Identity]
public Date DateModified { get; set; }
}请列出正确的步骤来配置DB以处理事务元日期,比如需要在模型中设置什么,以及在DB上下文配置器中是否需要采取任何操作。我在寻找这样的东西:“您需要知道的关于ASP.NET MVC数据处理的所有信息”,但是没有多少涉及到这个方面。
提前谢谢。
发布于 2014-12-01 03:30:48
我将从实体框架的角度来考虑这个问题。
基本上,您需要执行以下操作:
1-我将定义一个像ITrackable接口的接口,如果这些模型需要跟踪DateCreated和DateModified特性,我的模型就会实现这个接口。
2-不知何故,您的模型知道它是否是添加/修改的实体,因为这将决定设置哪个属性(同时用于添加实体,而只用于修改实体的DateModified )。
3-使用实体中的DbContext -框架添加了一个扩展方法,当您试图通过SaveChanges或SaveChangesAsync保存实体时,需要调用该扩展方法,该方法将循环遍历跟踪的实体,并根据实体的状态设置DateCreated和DateModified属性。
所以你的模型会是这样的:
public class Person : IdentityUser, ITrackable
{
[Required]
public string Name { get; set; }
public Date DateOfBirth { get; set; }
public string Address { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateModified { get; set; }
}ITrackable看上去就像
public interface ITrackable
{
public DateTime DateCreated { get; set; }
public DateTime DateModified { get; set; }
}扩展方法如下所示:
internal static class ContextHelper
{
internal static void SyncObjectsStatePreCommit(this DbContext dbContext)
{
foreach (var dbEntityEntry in dbContext.ChangeTracker.Entries())
{
// do any other stuff you want.
// ..
// ..
// work with ITrackable entities
var trackableObject = dbEntityEntry.Entity as ITrackable;
// we need to set/update trackable properties
if (trackableObject == null)
{
continue;
}
var dateTime = DateTime.Now;
// set createddate only for added entities
if (entityState.ObjectState == ObjectState.Added)
{
trackableObject.CreatedDate = dateTime;
}
// set LastUpdatedDate for any case other than Unchanged
if (entityState.ObjectState != ObjectState.Unchanged)
{
trackableObject.ModifiedDate = dateTime;
}
}
}
}例如,在您的dbContext保存方法中,需要调用此方法来设置所有这些属性。
public override Task<int> SaveChangesAsync()
{
this.SyncObjectsStatePreCommit();
return base.SaveChangesAsync();
}希望这能有所帮助。
发布于 2017-06-29 11:05:19
我发现上面的答案有点混乱,但是我认为更直接的解决方案是覆盖SaveChanges方法,如本博客中所描述的。
此解决方案还使用ITrackable接口,当触发SaveChanges时,它将检查Entity是否实现此接口:
public override System.Threading.Tasks.Task<int> SaveChangesAsync()
{
foreach (var auditableEntity in ChangeTracker.Entries<ITrackableEntity>())
{
if (auditableEntity.State == EntityState.Added ||
auditableEntity.State == EntityState.Modified)
{
// implementation may change based on the useage scenario, this
// sample is for forma authentication.
string currentUser = HttpContext.Current.User.Identity.GetUserId();
DateTime currentDate = SiteHelper.GetCurrentDate();
// modify updated date and updated by column for
// adds of updates.
auditableEntity.Entity.ModifiedDateTime = currentDate;
auditableEntity.Entity.ModifiedUserId = currentUser;
// pupulate created date and created by columns for
// newly added record.
if (auditableEntity.State == EntityState.Added)
{
auditableEntity.Entity.CreatedDateTime = currentDate;
auditableEntity.Entity.CreatedUserId = currentUser;
}
else
{
// we also want to make sure that code is not inadvertly
// modifying created date and created by columns
auditableEntity.Property(p => p.CreatedDateTime).IsModified = false;
auditableEntity.Property(p => p.CreatedUserId).IsModified = false;
}
}
}
return base.SaveChangesAsync();
}发布于 2022-02-02 08:32:28
我认为实体框架文档明确指出:
警告 与默认值或计算列不同,我们没有指定如何生成值;这取决于所使用的数据库提供程序。数据库提供程序可能会自动设置某些属性类型的值生成,但其他属性类型可能要求您手动设置如何生成值。例如,在Server上,当GUID属性配置为在add上生成的值时,提供程序将自动执行值生成客户端,使用一种算法生成最佳顺序GUID值。但是,指定在日期时间属性上添加生成的值不会产生任何效果(关于日期时间值生成,请参见下面一节)。类似地,配置为在add或update上生成并标记为并发令牌的字节属性使用行版本数据类型设置,以便在数据库中自动生成值。但是,指定在Add上生成的值没有任何效果。
这是在第284页的文档下载时(假设你的不重复某些部分)。的医生接着说
备注
根据所使用的数据库提供程序,值可以由EF或数据库中的客户端生成。如果该值是由数据库生成的,那么在将实体添加到上下文时,EF可能会分配一个临时值;然后,在保存更改期间,该临时值将被数据库生成的值替换。有关更多信息,请参见关于临时值的文档。
不管怎样,RTFM!!
https://stackoverflow.com/questions/27221137
复制相似问题