在我的数据库中的每个对象上,我都有CreatedBy,CreatedOn,ModifiedOn和ModifiedBy的审计字段。 CreatedBy和ModifiedBy映射到我创建的用户对象以映射到我的用户表。我最初在这些字段中存储UserId(主键),并且映射定义的映射定义很好
<many-to-one name="CreatedBy" column="CreatedBy" lazy="proxy"></many-to-one>
。
但是,我想切换这些字段来存储用户名,但我找不到如何从非主键字段加载持久用户实体。我已经研究过IUserTypes,ICompositeUserType,事件监听器以及其他一些随机的东西,但我似乎无法完全发挥作用。
截至目前,我已经添加了一个CreatedByName和ModifiedByName字段,用于存储用户名,而原始字段仍然存储ID(在使用CompositeUserType时这样做),所以我有ID和用户名,我可以使用需要的。
这似乎应该足够普遍,应该有一个解决方案,但我找不到任何东西。
答案 0 :(得分:1)
您可以在property-ref
中指定many-to-one
属性以指定任意加入属性。
http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-manytoone
答案 1 :(得分:0)
由于审计不是业务问题,我发现解决此问题的最佳方法是使用NHibernate事件监听器。
示例侦听器可能如下所示:
namespace ADT.Data.Repositories.NHibernate.EventListeners
{
public class PreInsertEventListener : IPreInsertEventListener
{
public bool OnPreInsert(PreInsertEvent @event)
{
var audit = @event.Entity as IHaveAuditInformation;
if (audit == null)
return false;
var time = DateTime.Now;
var user = Security.GetLoggedInUser();
Set(@event.Persister, @event.State, "LogDate", time);
Set(@event.Persister, @event.State, "User", user);
audit.LogDate = time;
audit.User = user;
return false;
}
private void Set(IEntityPersister persister, object[] state, string propertyName, object value)
{
var index = Array.IndexOf(persister.PropertyNames, propertyName);
if (index == -1)
return;
state[index] = value;
}
}
}
我记录用户和插入实体的日期。还有一个preupdate听众。当然,您必须使用NHibernate Configuration配置侦听器。