2010-01-02 9 views
1

J'ai essayé pendant un certain temps de m'expliquer comment accomplir ma mission, et en fait je ne suis même pas sûr que la direction dans laquelle je me dirige, est en effet une question discutable de mes tables SQL - mais c'est le plus concis que j'ai pu imaginer.NHibernate mapping - comment y parvenir

Mon problème est assez simple à décrire. J'ai une table contenant des commentaires, avec une clé étrangère à ma table utilisateur (qui représente l'auteur du commentaire). Pour tenter de supporter correctement les utilisateurs anonymes, j'ai décidé de rendre cette clé étrangère invalide - et je fournis également 3 colonnes pour spécifier le nom, l'email et le site Web où je souhaite stocker l'information pertinente dans le cas où l'utilisateur est anonyme - ces champs sont également nullable.

Donc en bref

  • Si l'utilisateur est connecté, la clé étrangère contiendra l'ID de l'utilisateur et le nom, e-mail et le site Web seront nuls.
  • Si l'utilisateur n'est pas connecté, la clé étrangère sera null et Nom, Email et Site Web contiendront des données sur l'utilisateur.

Dans mon modèle de domaine, je souhaite mapper ceci à une classe User (une propriété, Author, sur ma classe de commentaire). Cette classe d'utilisateurs possède alors une propriété appelée "IsAnonymous" - qui doit être définie en conséquence.

Idéalement, j'aurais une configuration de mappage qui mapperait cette propriété Auteur en fonction des valeurs de la clé étrangère et assignerait ces propriétés correctes. J'ai déjà un mappage pour ma classe User qui le mappe à la table User, mais je ne suis pas sûr de savoir comment je ferais cela dans l'autre sens.

J'ai essayé d'explorer l'interface IUserType, mais je ne comprends pas très bien comment je voudrais lire ce problème de 2 tables différentes.

Existe-t-il une manière raisonnable de le faire en utilisant ma structure de base de données actuelle - ou devrais-je envisager de changer ma disposition, et si oui, à quoi? Je suis passé d'avoir une simple colonne dans ma table utilisateur indiquant un utilisateur anonyme, mais cela a commencé à me donner des problèmes lorsque la colonne Nom est définie comme une clé unique. Je veux que les utilisateurs enregistrés aient des noms uniques mais pas des utilisateurs anonymes.

Merci pour votre temps.

EDIT: Relisez que et avons décidé peut-être quelques ASCII/diagrammes pseudo-SQL me serait utile

User 
----- 
UserId Guid PRIMARY KEY 
Name nvarchar(200) UNIQUE KEY NOT NULL 
Email nvarchar(200) NOT NULL 
Website nvarchar(200) NOT NULL 

Comment 
------- 
CommentId Guid PRIMARY KEY 
UserId GUID - FK-USER 
Name nvarchar(200) 
Email nvarchar(200) 
Website nvarchar(200) 

Répondre

1

j'aurais quelque chose comme ça

//map this in NH 
public virtual User LoggedInCreator {get;set;} 
//Not mapped 
public virtual User CreatorInformation { 
    get { 
     if(LoggedInCreator != null) return LoggedInCreator; 
     return new User { 
       Name = AnonymousCommenterName, 
       Email = AnonymousCommenterEmail, 
       Website= AnonymousCommenterWebsite 
      }; 
    } 
} 
public void SetAnonymouscommenter(string name, string email, string website) 
{ 
    LoggedInCreator = null; 
    AnonymousCommenterName = name; 
    AnonymousCommenterEmail = email; 
    AnonymousCommenterWebsite = website; 
} 

Cependant, si vous voulez le faire dans un beaucoup plus propre façon, vous utiliseriez une grande fonctionnalité de NHibernate, qui est en mesure de mapper champs et également les propriétés de mappage qui stockent leurs valeurs dans les champs.
Voici ce qu'est une mise en œuvre plus propre serait:

protected User _commenter; 
public virtual User Commenter 
{ 
    get { 
     if(_commenter != null) return _commenter; 
     return new User { 
       Name = AnonymousCommenterName, 
       Email = AnonymousCommenterEmail, 
       Website= AnonymousCommenterWebsite 
     }; 
    } 
    set { 
     bool isAnonymous = value.Id == 0; 
     _commenter = isAnonymous ? null : value; 
     AnonymousCommenterName = isAnonymous ? value.Name : null; 
     AnonymousCommenterEmail = isAnonymous ? value.Email : null; 
     AnonymousCommenterWebsite = isAnonymous ? value.Website : null; 
    } 
} 

Vous pouvez voir qu'ils sont essentiellement la même idée que, juste un nettoyage à l'aide des fonctionnalités NHibernate.

+0

Cela pourrait fonctionner!Je travaille actuellement sur une approche où je sous-classe ma classe de commentaire dans mon cas d'utilisation spécifique de NHibernate et l'utilise uniquement dans mon code NHibernate. Je reviendrai une fois que j'aurai fini de tester ceci pour voir si ça peut marcher :). – kastermester

+0

Merci, vos suggestions m'ont permis d'avancer d'une manière qui semble fonctionner. C'est un peu de code pour l'implémenter dans la couche NH, mais d'un autre coté ça fait du bien de travailler avec d'autres et il est stocké dans la base de données d'une manière qui a du sens dans ma tête :) – kastermester