更新模型中的常用字段

时间:2016-02-19 17:05:56

标签: c# asp.net entity-framework design-patterns asp.net-core

我遇到了重复代码的问题。 我有多个具有相同属性的模型:

public DateTimeOffset CreatedDate { get; set; }
public DateTimeOffset ModifiedDate { get; set; }
public virtual AppUser CreatedBy { get; set; }
public virtual AppUser ModifiedBy { get; set; }

现在我正在编写相同的代码来更新控制器的多个操作中的这些字段,如下所示:

model.CreatedBy = user;
model.CreatedDate = now;
model.ModifiedBy = user;
model.ModifiedDate = now; 

我想知道是否有任何方法或模式可以避免这些重复的代码?在这种情况下有任何最佳做法吗? 我正在使用EntityFrameworkASP.net Core Web API。 (如果有意义的话)。

2 个答案:

答案 0 :(得分:1)

您可以创建界面,例如:

public interface IMetaDataHolder{
    DateTimeOffset CreatedDate { get; set; }
    DateTimeOffset ModifiedDate { get; set; }
    AppUser CreatedBy { get; set; }
    AppUser ModifiedBy { get; set; }
}

将它添加到您的模型中,在基本控制器内部,您可以使用类似的东西:

protected void AssignMetaData(IMetaDataHolder metaDataHolder){
    var now = DateTime.UtcNow; //or whatever
    var user = Session.User; //or whatever

    metaDataHolder.CreatedBy = user;
    metaDataHolder.CreatedDate = now;
    metaDataHolder.ModifiedBy = user;
    metaDataHolder.ModifiedDate = now; 
}

这样在你的Action Methods中你只能调用AssignMetaData方法而不是重复赋值调用。

答案 1 :(得分:1)

您可以使用这些属性创建类似AuditedEntity的基本模型,并从其继承其余模型:

public class AuditedEntity
{
    public DateTimeOffset CreatedDate { get; set; }
    public DateTimeOffset ModifiedDate { get; set; }
    public virtual AppUser CreatedBy { get; set; }
    public virtual AppUser ModifiedBy { get; set; }
}

在您的服务层中,您可以使用方法WriteAuditInformation(AuditedEntity model)来调用Create()Update()方法:

public void WriteAuditInformation(AuditedEntity model)
{
    model.CreatedBy = user;
    model.CreatedDate = now;
    model.ModifiedBy = user;
    model.ModifiedDate = now;
}

另一种方法是,如果您可以在上下文类中访问user变量,则覆盖SaveChanges()方法:

public override int SaveChanges()
{
    var now = DateTime.Now;
    var entities = ChangeTracker.Entries<AuditedEntity>();
    foreach (var item in entities)
    {
        if (item.State == EntityState.Added)
        {
            item.CreatedBy = user;
            item.CreatedDate = now;
            item.ModifiedBy = user;
            item.ModifiedDate = now;
        }
        else if (item.State == EntityState.Modified)
        {
            item.ModifiedBy = user;
            item.ModifiedDate = now;
        }
    }

    return base.SaveChanges();
}