如何在插入/修改实体后立即填充复杂类型

本文关键字:填充 复杂 类型 实体 插入 修改 | 更新日期: 2023-09-27 18:12:43

我有这个Complex Type包含在我的实体类中,例如:

public class Logbook
{
  public string CreatedBy { get; set; }
  public DateTimeOffset DateCreated { get; set; }
  public string ModifiedBy { get; set; }
  public DateTimeOffset DateModified { get; set; }
}

然后我的主类:

public class Customer
{
  public int Id { get; set; }
  public string Name { get; set; }
  public Logbook Logbook { get; set; }
}

然后将类Logbook设置为复杂类型。我的问题是,我想知道如何在Customer实体插入/修改后立即设置Logbook中的值?例如,将DateCreated设置为DateTime.UtcNow,将CreatedBy设置为用户名。等等......任何帮助都将非常感激。谢谢!

编辑:

我使用Entity Framework为我的数据访问。这就是保存Customer

的方法
public ActionResult Create(Customer customer)
{
  if ( Model.IsValid() )
  {
    _customerRepository.Insert(customer);
    return View("Index");
  }
  return View(customer);
}

如何在插入/修改实体后立即填充复杂类型

我不知道是否有可能自动完成。在我的例子中,我准备了一个特殊的通用方法来处理日志中的实体更新(在任何情况下都是IoC友好的:)):

public T PrepareLogbookProperty<T>(T model)
{
    if (model == null)
    {
        throw new ArgumentNullException("model");
    }
    var dynamicModel = (dynamic)model;
    Entity value;
    try
    {
        value = dynamicModel.Logbook as Logbook;
    }
    catch (RuntimeBinderException)
    {
        throw new NoLogbookPropertyFound();
    }
    value = this.PassLog(value); // THAT METHOD PASSES CURRENT USER OR DATE TIME.
    dynamicModel.Logbook= value;
    return model;
}

它有一个缺点——不幸的是它是动态的。为了处理其他情况,我准备了其他重载函数:

public TEntity PrepareLogbookProperty<TEntity>(TEntity model, Expression<Func<TEntity, Logbook>> entityExpression)
{
    if (model == null)
    {
        throw new ArgumentNullException("model");
    }
    var memberExpression = (MemberExpression)entityExpression.Body;
    var property = (PropertyInfo)memberExpression.Member;
    var value = property.GetValue(model) as Logbook;
    value = this.PassLog(value);
    property.SetValue(model, value);
    return model;
}

用法:

this.helper.PrepareLogbookProperty(customer, cust => custom.MyOtherLogBook); // expression version

this.helper.PrepareLogbookProperty(product); // dynamic version (I assume that product has Logbook property

方法在每个SaveChanges()之前手动调用。

不幸的是,我不能改变DB模式和它的设计方式——所以这个解决方案适合我。

示例传递日志:

private Logbook PassLog(Logbook entity)
{
    if (entity == null)
    {
        entity = this.NewLogbook();
    }
    entity.EditedDate = this.dateTimeProvider.Now;
    entity.EditorID = this.services.CurrentUser.ID;
    return entity;
}

你想要这样的东西吗?

public class Logbook
{
  public Logbook(string username)
  {
    this.CreatedBy = username;
    this.DateCreated = DateTime.UtcNow; //NB: ideally your database would provide this to ensure if deployed on multiple servers you'd have one date source
    this.ModifiedBy = username;
    this.DateModified = DateTime.UtcNow; //as above
  }
  public void Modify(string username)
  {
    this.ModifiedBy = username;
    this.DateModified = DateTime.UtcNow; //as above
  }
  public string CreatedBy { get; set; }
  public DateTimeOffset DateCreated { get; set; }
  public string ModifiedBy { get; set; }
  public DateTimeOffset DateModified { get; set; }
}
public class Customer
{
  private int id;
  public int Id { 
    get { return this.id; } 
    set { this.id = value; this.OnCreateOrModify(); }
  }
  private string name;
  public string Name { 
    get { return this.name; }
    set { this.name = value; this.OnCreateOrModify(); }
  }
  public Logbook Logbook { get; private set; } //presumably you don't want other classes to amend this
  private void OnCreateOrModify()
  {
    var username = System.Environment.UserName;  //or pass something into your class contructor to provide a username
    if (this.Logbook == null) //create
        this.Logbook = new LogBook(username);
    else //modify
        this.Logbook.Modify(username);
  }
}