2010-04-18 6 views
1

J'ai cette structure de table et voudrais la mapper en utilisant Hibernate Fluent (sous-classe si possible). Je ne peux pas modifier la structure car la base de données contient trop d'enregistrements et peut entraîner le retraitement d'applications majeures. Il serait plus facile si la table Id from Party était une clé étrangère dans la table de personne et d'organisation, mais dans le scénario particulier, la base de données a une clé de personne et d'organisation en tant que clé étrangère dans la table de fête. Toute aide est la bienvenue.Comment mapper une relation un à un dans Fluent NHibernate. J'ai essayé tout le reste

Party Table

Id personID organizationid

personne Table

Id FName LName

Table Organisation

Id OrgName OrgDescription

+0

Références (x => x.Personnel, "PersonId"). Not.Nullable(); Références (x => x.Organization, "OrganizationId"). Not.Nullable(); Ne fonctionne pas? – jweyrich

Répondre

0

Vous ne pouvez pas mapper une table de liaison avec la conversion automatique si elle contient des champs autres que les deux ID qui composent l'ID composite. Dans votre cas, votre table Party a un champ Id qui interrompt les règles d'auto-construction car elle n'est pas bien conçue (un ID composite ne doit pas avoir d'identifiant auto-incrémenté, bien que nous le fassions pour l'indexation). Pour résoudre ce problème, il vous suffira de créer un ClassMap for Party et de mapper Id en tant que Id et référence Person and Organization. Puis, dans vos entités Personne et Organisation, au lieu de créer un mappage HasManyToMany à Partie, vous créez un HasMany à l'entité Partie. Vraiment, ce que vous faites correspond explicitement au code pour ressembler plus à ERD, alors que l'automappage implique des relations plusieurs-à-plusieurs via une table de liens uniquement s'il ne contient qu'une clé primaire composite. Cela m'a stupéfié pendant trois jours et j'ai pris cette route comme un "hack", seulement pour lire plus tard cette explication dans le groupe google de Fluent NHibernate il y a quelques semaines.

J'espère que cela aide, sinon je peux jeter ensemble du code pour vous. Voir aussi my post about the same situation.

modifier:

Voici comment cela ressemblerait à un niveau assez élevé. Rappelez-vous, vous devrez initialiser vos collections dans vos constructeurs d'entités et créer des méthodes setter. Voir Getting Started

public class Party { 
    public virtual int Id { get; set; } 
    public virtual Person Person { get; set; } 
    public virtual Organization Organization { get; set; } 
} 
public class PartyMap : ClassMap<Party> { 
    public PartyMap() { 
     Id(x => x.Id); 
     References(x => x.Person); 
     References(x => x.Organization); 
    } 
} 
public class Person { 
    public virtual int Id { get; set; } 
    public virtual string FName { get; set; } 
    public virtual string LName { get; set; } 
    public virtual ICollection<Party> Parties { get; set; } 
} 
public class PersonMap : ClassMap<Person> { 
    public PersonMap() { 
     Id(x => x.Id); 
     Map(x => x.FName); 
     Map(x => x.LName); 
     HasMany(x => x.Parties); 
    } 
} 
public class Organization { 
    public virtual int Id { get; set; } 
    public virtual string OrgName { get; set; } 
    public virtual string OrgDescription { get; set; } 
    public virtual ICollection<Party> Parties { get; set; } 
} 
public class OrganizationMap : ClassMap<Organization> { 
    public OrganizationMap() { 
     Id(x => x.Id); 
     Map(x => x.OrgName); 
     Map(x => x.OrgDescription); 
     HasMany(x => x.Parties); 
    } 
} 
+0

Merci Jim. C'est drôle que je regardais la table du parti tout ce temps et n'ai pas réalisé que la table de partie est une table de lien, l'identification automatique d'incrémentation dans cette table me jetait outre de la piste. La chose est, les données dans la table de partie a contraint où vous pouvez avoir soit PersonId ou OrganizationId, il essaye de le mapper comme une relation un à un, donc je suis d'accord avec vous qui l'a conçu probablement manqué ce problème. Je suis nouveau à NHibernate, je serai très heureux si vous avez fourni du code. Très appréciée. Rusty –

+0

@Rusty: J'étais beaucoup plus occupé que je ne l'avais prévu. J'ai donc monté ce code et j'espère que cela vous aidera à vous orienter dans la bonne direction. Je suis sûr qu'il y a d'autres façons de le faire (en utilisant une convention pour la classe Party, peut-être?) Mais c'était la façon la plus simple pour moi, puisque toutes mes tables de liens ont aussi des champs d'audit, des champs de notes juste pour lier deux tables ensemble. –