Nous avons une base de données héritée que nous ne pouvons pas modifier. Et nous essayons de passer à la NHibernate au lieu de l'ancienne couche DataAccess qui est une poubelle et qui est trop lente.NHibernate navigateurs mappés à la partie d'un problème de clé composite - utilisation de la base de données existante
il a des tables comme celles-ci:
Table GPI a (PU_ID, PAR_ID, données, Data2) colonnes
table BLOC a (GA_ID, données, PAR_ID) colonnes
table COMPANY a (PU_ID, données) colonnes
j'avais créé ces correspondances pour les tableaux ci-dessus:
GPI
<class name="GroupPartnerInterest" table="[GPI]">
<composite-id >
<key-property name="GroupId" column="PAR_ID" />
<key-property name="CompanyId" column="PU_ID" />
</composite-id>
<property name="data" column="Data"/>
<property name="data2" column="Data2"/>
<many-to-one name="Company" fetch="select" cascade="none">
<column name="PU_ID"/>
</many-to-one>
<set name="Blocks" cascade="none" inverse="true" fetch="select">
<key property-ref="GroupId">
<column name="PAR_ID"/>
</key>
<one-to-many class="Block"/>
</set>
</class>
BLOC
<class name="Block" table="[BLOCK]" >
<id name="BlockId" column="GA_ID" >
<generator class="assigned"/>
</id>
<property name="data" column="Data"/>
<property name="GroupId" column="PAR_ID"/>
<set name="GroupPartnerInterests" cascade="all-delete-orphan" fetch="select">
<key property-ref="GroupId">
<column name="PAR_ID"/>
</key>
<one-to-many class="GroupPartnerInterest"/>
</set>
</class>
COMPANY
<class name="Company" table="[COMPANY]">
<id name="CompanyId" column="PU_ID">
<generator class="assigned"/>
</id>
<property name="data" column="Data"/>
<set name="GroupPartnerInterests" cascade="none" inverse="true" fetch="select">
<key>
<column name="PU_ID"/>
</key>
<one-to-many class="GroupPartnerInterest"/>
</set>
</class>
Les classes sont très simple et clair. Tous implémentent les méthodes Equals et GetHashCode.
Voici la liste des navigateurs qui fonctionnent:
- GroupPartnerInterest.Company - fonctionne très bien
- Company.GroupPartnerInterests - fonctionne très bien
- GroupPartnerInterest.Company - fonctionne très bien
Et ces deux échouent:
- Block.GroupPartnerInterests:
J'ai une unité test:
[TestMethod]
public void TestGroupPartnerInterests()
{
using (ISession session = SessionFactory.OpenSession())
{
IList<Block> blocks = session.CreateCriteria(typeof(Block))
.SetMaxResults(5).List<Block>();
foreach (var block in blocks)
{
TestContext.WriteLine("Block #{0}", block.BlockId);
if (block.GroupPartnerInterests != null)
{
foreach (GroupPartnerInterest gpi in block.GroupPartnerInterests)
{
TestContext.WriteLine("Company '{0}':", gpi.Company.CompanyId);
}
}
}
}
}
Si je commente sur la cartographie de navigation blocs dans les travaux d'essai de cartographie GPI et sorties des données:
Block #1
Company 'LALA':
Company 'LALA SA':
Block #2
Company 'BG PO':
Company 'LIMPOPO':
Block #3
Company 'HAHA':
Company 'Other partner(s)':
Block #4
Mais le test échoue avec l'erreur suivante:
NHibernate.LazyInitializationException: Initializing[Model.EntityClasses.Block#999]-failed to lazily initialize a collection of role: Model.EntityClasses.Block.GroupPartnerInterests, no session or session was closed.
Le '999' est PAR_ID existant - les données sont cohérentes: il y a deux blocs avec ce PAR_ID et quelques enregistrements dans GPI. Pourquoi cela ferme-t-il la session à un moment donné?
- GroupPartnerInterest.Blocks:
Le test unitaire est presque le même que je l'ai mentionné ci-dessus, les propriétés seulement différentes sont utilisées. Une erreur est ci-dessous:
NHibernate.MappingException: NHibernate.MappingException: property not found: GroupId on entity Model.EntityClasses.GroupPartnerInterest.
Si je retire "property-ref = GroupId" de l'élément du navigateur blocs dans la cartographie GPI, je vais faire l'exception suivante:
NHibernate.FKUnmatchingColumnsException: NHibernate.FKUnmatchingColumnsException: Foreign key (FKA3966498349694F:[BLOCK] [PAR_ID])) must have same number of columns as the referenced primary key ([GPI] [PAR_ID, PU_ID]).
Est Y at-il un moyen de mapper les Blocs à GPI pour que le navigateur GroupPartnerInterest.Blocks fonctionne?
Merci, Alex
Merci pour la réponse en profondeur! Je vais essayer de convaincre notre équipe de modifier un peu le schéma DB: ajoutez une clé primaire autogénérée (incrémentation) à la table GPI. Cela va résoudre le problème de propriété-ref = GroupId et devrait résoudre mes problèmes de navigation – LucID
J'ai un problème très similaire. J'ai essayé de mapper ce scénario avec des mappages XML et fluides, mais pas de joie. Malheureusement, je ne peux pas changer le schéma pour le moment. Puis-je vous aider à jeter un coup d'œil? http://stackoverflow.com/questions/25191275/fluent-nhibernate-map-hasmany-to-entity-table-with-no-primary-key –