扩展的基本类型和自动更新的实体审计信息 [英] Extend base type and automatically update audit information on Entity
问题描述
我有一个具有每个表上审核信息的实体模型(50 +表)
I have an entity model that has audit information on every table (50+ tables)
CreateDate
CreateUser
UpdateDate
UpdateUser
目前,我们正在通过程序更新审计信息。
Currently we are programatically updating audit information.
例如:
if(changed){
entity.UpdatedOn = DateTime.Now;
entity.UpdatedBy = Environment.UserName;
context.SaveChanges();
}
但我在寻找一个更自动化的解决方案。在保存更改,如果创建一个实体/更新,我想将它们发送到数据库存储之前自动更新这些字段。
But I am looking for a more automated solution. During save changes, if an entity is created/updated I would like to automatically update these fields before sending them to the database for storage.
我如何能做到这一点任何建议?我想preFER不做任何反映,所以使用文本模板是不是出了问题。
Any suggestion on how i could do this? I would prefer to not do any reflection, so using a text template is not out of the question.
一个解决方案已经提出来覆盖SaveChanges的,做它在那里,但为了实现这一目标,我将要么必须使用反射(在此我并不想这样做),或者派生的基类。假设我沿着这条路走下去我将如何实现这一目标?
A solution has been proposed to override SaveChanges and do it there, but in order to achieve this i would either have to use reflection (in which I don't want to do ) or derive a base class. Assuming i go down this route how would I achieve this?
例如
EXAMPLE_DB_TABLE
CODE
NAME
--Audit Tables
CREATE_DATE
CREATE_USER
UPDATE_DATE
UPDATE_USER
如果我创建一个基类
And if i create a base class
public abstract class IUpdatable{
public virtual DateTime CreateDate {set;}
public virtual string CreateUser { set;}
public virtual DateTime UpdateDate { set;}
public virtual string UpdateUser { set;}
}
的最终目标是要能够做这样的事情......
The end goal is to be able to do something like...
public overrride void SaveChanges(){
//Go through state manager and update audit infromation
//FOREACH changed entity in state manager
if(entity is IUpdatable){
//If state is created... update create audit.
//if state is updated... update update audit
}
}
但我不知道我该怎么去生成code,将扩展接口。
But I am not sure how I go about generating the code that would extend the interface.
推荐答案
下面是最终的解决方案。
Here was the final solution.
我基本上是检查我的模式,为4个属性的presence。如果实体包含
I basically check my model for the presence of 4 properties. If the entity contains
InsertedOn和InsertedBy和UpdatedOn和UpdatedBy我生成(使用TT文件)实现了IAuditable接口,接口下的实体。
InsertedOn and InsertedBy and UpdatedOn and UpdatedBy I generate (using a tt file) the following entity that implements an IAuditable interface.
public interface IAuditable
{
void SetInsertedOn(DateTime date);
void SetInsertedBy(string user);
void SetUpdatedOn(DateTime date);
void SetUpdatedBy(string user);
}
public partial class ExampleDBtable: EntityObject, Audit.IAuditable
{
//Normal EDMX stuff here..
public static ExampleDBtable CreateExampleDBtable(int id, string code, string name, DateTime insertedOn, string insertedBy, DateTime updatedOn, string updatedBy)
{
}
//Extension points.
#region IAuditable Members
public void SetInsertedOn(DateTime date)
{
this._InsertedOn = date;
}
public void SetInsertedBy(string user)
{
this._InsertedBy = user;
}
public void SetUpdatedOn(DateTime date)
{
this._UpdatedOn = date;
}
public void SetUpdatedBy(string user)
{
this._UpdatedBy = user;
}
#endregion
}
我也产生code处理审计信息的更新
I also generate code to handle the updating of audit information
public ExampleDBObjectContext(string connectionString) : base(connectionString, "publicExampleDBObjectContext")
{
this.SavingChanges += new EventHandler(UpdateAuditInformation);
this.OnContextCreated();
}
然后最后我实现了UpdateAuditInformation
And then finally I implemented the UpdateAuditInformation
foreach (ObjectStateEntry entry in
context.ObjectStateManager.GetObjectStateEntries(
EntityState.Added | EntityState.Modified))
{
//Start pseudo code..
if(entry.Entity is IAuditable){
IAuditable temp = entry.Entity as IAuditable;
temp.SetInsertedOn(DateTime.Now);
temp.SetInsertedBy(Env.GetUser());
...
}
}
我选择不显示.TT文件,因为它看起来可怕的编辑器。
I opted not to show the .tt file because it looks horrible in the editor.
这篇关于扩展的基本类型和自动更新的实体审计信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!