2011-03-22 3 views
1

Sur chaque objet de ma base de données, j'ai des champs d'audit pour CreatedBy, CreatedOn, ModifiedOn et ModifiedBy. le CreatedBy et ModifiedBy mapper à un objet Utilisateur que j'ai créé pour mapper à ma table d'utilisateurs. À l'origine, je stockais l'UserId (clé primaire) dans ces champs et tout mappé correctement avec une définition de mappage de <many-to-one name="CreatedBy" column="CreatedBy" lazy="proxy"></many-to-one>.NHIbernate: Mappage Audit utilisateur

Cependant, je veux changer ces champs pour stocker le nom d'utilisateur à la place, mais je ne trouve pas comment charger l'entité utilisateur persistante à partir du champ non-clé primaire. J'ai regardé dans IUserTypes, ICompositeUserType, les écouteurs d'événement, et quelques autres choses aléatoires, mais je ne peux pas sembler fonctionner complètement quelque chose. En ce moment, j'ai ajouté un champ CreatedByName et ModifiedByName qui stocke le nom d'utilisateur alors que les champs d'origine stockent toujours l'ID (fait ceci en jouant avec CompositeUserType), donc j'ai l'ID et le nom d'utilisateur que je peux utiliser si besoin.

Cela semble être quelque chose qui devrait être assez commun pour qu'il y ait une solution, mais je ne trouve rien.

Répondre

1

Vous pouvez spécifier l'attribut property-ref dans votre many-to-one pour spécifier une propriété de jointure arbitraire.

http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-manytoone

+0

Merci. J'ai fini par trouver ça peu de temps après que j'ai posté ça. On dirait que ça marche contre la mise en cache L2 que j'ai mise en place car elle fait des requêtes sans la clé primaire, donc je devrais peut-être repenser comment je veux faire tout cela. – jwynveen

0

Depuis la vérification n'est pas une entreprise commerciale, j'ai trouvé la meilleure façon de résoudre ce problème est d'utiliser des écouteurs d'événements NHibernate.

Un écouteur d'échantillon pourrait ressembler à ceci:

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

-je me connecter à l'utilisateur et la date à laquelle l'entité a été insérée. Il y a aussi un écouteur preupdate. Bien sûr, vous devrez configurer les écouteurs avec NHibernate Configuration.