C# 在ASP.NET MVC 5中创建和修改日期

C# 在ASP.NET MVC 5中创建和修改日期,c#,asp.net-mvc,entity-framework,datetime,asp.net-mvc-5,C#,Asp.net Mvc,Entity Framework,Datetime,Asp.net Mvc 5,我正在做一个代码优先的项目,我需要数据库来处理DateCreated和DateModified 该应用程序在IIS Express上运行,在开发人员计算机上使用LocalDB,并将在部署服务器上使用SQL Server 2012和IIS 7.5 我有以下型号: public class Person : IdentityUser { [Required] public string Name { get; set; } public Date DateOfBirth { get;

我正在做一个代码优先的项目,我需要数据库来处理DateCreatedDateModified

该应用程序在IIS Express上运行,在开发人员计算机上使用LocalDB,并将在部署服务器上使用SQL Server 2012和IIS 7.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 context configurator中执行任何操作。我在搜索类似这样的内容:“关于ASP.NET MVC日期处理,您需要了解的所有内容”,但不能涉及到这一方面


提前感谢。

我将从实体框架的角度考虑这一点

您基本上需要执行以下操作:

1-我将定义一个类似ITrackable接口的接口,如果这些模型需要跟踪DateCreated和DateModified属性,我将让我的模型实现该接口

2-不知何故,您的模型知道它是否是am添加/修改的实体,因为这将决定要设置的属性(对于添加的实体和仅针对修改的实体的DateModified)

3-使用实体框架中的DbContext添加一个扩展方法,当您试图通过SaveChanges或SaveChangesSync保存实体时,需要调用该扩展方法,该方法将循环跟踪实体,并根据实体的状态设置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; }
}
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;
            }
        }
    }
}
ITrackable看起来像什么

public interface ITrackable
{
    public DateTime DateCreated { get; set; }

    public DateTime DateModified { get; set; }
}
扩展方法如下所示:

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; }
}
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();
}
public覆盖任务SaveChangesAsync()
{
this.SyncObjectsStatePreCommit();
返回base.saveChangesSync();
}

希望这能有所帮助。

我发现上面的答案有点让人困惑,但是我认为更直接的解决方案是覆盖本节中描述的
SaveChanges
方法

此解决方案还使用
ITrackable
接口,当触发
SaveChanges
时,它会检查
实体是否实现此接口:

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();
}
public override System.Threading.Tasks.Task SaveChangesAsync()
{
foreach(ChangeTracker.Entries()中的var auditableEntity)
{
如果(auditableEntity.State==EntityState.Add||
auditableEntity.State==EntityState.Modified)
{
//实现可能会根据使用场景而改变,这
//样品用于形式认证。
字符串currentUser=HttpContext.Current.User.Identity.GetUserId();
DateTime currentDate=SiteHelper.GetCurrentDate();
//修改的更新日期和按列更新
//添加一系列更新。
auditableEntity.Entity.ModifiedDateTime=当前日期;
auditableEntity.Entity.ModifiedUserId=当前用户;
//p计算的创建日期和按列创建
//新增加的记录。
if(auditableEntity.State==EntityState.Added)
{
auditableEntity.Entity.CreatedDateTime=currentDate;
auditableEntity.Entity.CreatedUserId=当前用户;
}
其他的
{
//我们还希望确保代码不是不恰当的
//修改创建日期和创建人列
属性(p=>p.CreatedDateTime).IsModified=false;
属性(p=>p.CreatedUserId).IsModified=false;
}
}
}
返回base.saveChangesSync();
}

您好,谢谢您详尽的回答。这是以编程方式保存日期。我的意图是让SQL Server负责更新这些日期字段,并利用
[DatabaseGeneratedOption.Identity]
@Annie
Identity
用于
自动递增的
唯一int值(因此不能将其用于日期列)。每个表只能有一个。如果要从数据库级别执行此操作,则必须通过触发器执行此操作,但仍然不能使用标识列。这取决于你从代码或使用触发器来做,但是人们更喜欢从代码来做,因为你有更多的控制权,例如,如果你想添加modifiedby或createdby列,这将只是将这些新字段与其他属性并排添加到上述代码中。谢谢Omar和Raphael。现在它是有意义的,我将尝试使它
ITrackable
。但是,我发现这个答案也很有用:.@JosephCasey要么将其定义为扩展方法并创建一个静态扩展类,其中包含上面定义的方法,要么将该方法定义为DbContext类的私有方法,这意味着您需要更改上面的代码以删除“this DbContext DbContext”参数并直接访问ChangeTracker.Entries(),因为它将可用于您的方法。