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

时间:2014-07-14 11:51:02

标签: c# asp.net-mvc entity-framework

我的实体类中包含此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设置为复杂类型。我的问题是,我想知道如果插入/修改Logbook实体后如何在Customer中设置值?比如说,将DateCreated设置为DateTime.UtcNow并将CreatedBy设置为用户名。依此类推。任何帮助将非常感激。谢谢!

编辑:

我正在使用Entity Framework进行数据访问。这就是我保存Customer

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

  return View(customer);
}

2 个答案:

答案 0 :(得分:2)

我不知道是否有可能自动完成。在我的情况下,我已经准备了一个特殊的通用方法来处理日志中的实体更新(在每种情况下它都是IoC :) :) :( / p>

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()之前手动调用方法。

不幸的是,我无法更改数据库架构及其设计方式 - 因此该解决方案适合我。

示例传递日志:

private Logbook PassLog(Logbook entity)
{
    if (entity == null)
    {
        entity = this.NewLogbook();
    }

    entity.EditedDate = this.dateTimeProvider.Now;
    entity.EditorID = this.services.CurrentUser.ID;

    return entity;
}

答案 1 :(得分:1)

你是否经历过这样的事情?

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);
  }
}