如何在插入/修改实体后立即填充复杂类型
本文关键字:填充 复杂 类型 实体 插入 修改 | 更新日期: 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);
}
}