我正在使用Entity Framework。我的所有数据库对象(实体)都有审计字段,例如'LastUpdateUserId,LastUpdateDate ......'
我希望有一个接受任何这些实体对象的泛型类,并为我填充字段。
到目前为止,我有:
public void PopulateAudit<T>(T entity)
{
}
但我似乎无法弄清楚如何引用我的实体,更新属性,然后返回它们。
如何以通用方式执行此操作,以便我可以在对象上调用方法来更新字段?
所以我可以这样做:
a = Context.accounts.FirstOrDefault(x => x.id == dto.Id);
PopulateAudit(a);
这可能吗?
答案 0 :(得分:3)
我可能会使用您的公共属性定义一个基本接口,然后将其写为扩展方法:
public interface IEntity
{
string LastUpdateUserID { get; set; }
DateTime LastUpdateDate { get; set; }
}
public static class EntityExtensions
{
/// <summary>
/// Extension Method for IEntity
/// </summary>
public static void PopulateAudit<T>(this T entity)
where T: IEntity
{
entity.LastUpdateDate = DateTime.Now;
entity.LastUpdateUserID = "john.doe"; //or pull this from a service somewhere
}
}
然后您可以在您的实体上调用它:
a = Context.accounts.FirstOrDefault(x => x.id == dto.Id);
a.PopulateAudit();
或者,如果您想要更好的IoC选项,可以将其定义为非扩展方法:
public class SomeServiceClass
{
private readonly IUserService _userService;
public SomeServiceClass(IUserService userService)
{
this._userService = userService;
}
public void PopulateAudit<T>(this T entity)
where T: IEntity
{
entity.LastUpdateDate = DateTime.Now;
entity.LastUpdateUserID = this._userService.GetCurrentUser();
}
}
a = Context.accounts.FirstOrDefault(x => x.id == dto.Id);
someServiceInstance.PopulateAudit(a);
答案 1 :(得分:1)
如果所有对象都来自公共基类,则不必使用模板
void Main()
{
var dt = new MyData();
FillTracking(dt);
}
public void FillTracking(TrackableObject obj)
{
obj.LastUpate = DateTime.Now;
}
public class TrackableObject
{
public DateTime LastUpate { get; set; }
}
public class MyData : TrackableObject
{
}
否则你可以使用反射..
void Main()
{
var dt = new MyData();
FillTracking(dt);
}
public void FillTracking(object data)
{
data.GetType().GetProperty("LastUpdate").SetValue(data, DateTime.Now);
}
public class MyData
{
public DateTime LastUpdate { get; set; }
}
请记住,反射代码不完整,您需要在尝试设置之前检查属性是否存在。
答案 2 :(得分:0)
您可以使用AutoMapper
将实体对象复制到POCO对象。 Here is a good walk-through和here如何使用它。