Nhibernate Fluent clé composite mapping
J'ai essayé de comprendre cette question pendant un temps assez long. J'ai un hacky moyen de le faire fonctionner.
Je veux juste savoir si c'est possible dans NHibernate Fluent de la cartographie.
Dire que j'ai deux tables par exemple:
Table ComissionLevel
{
Year,
ComissionLevelID,
... other properties ....
}
primary key (Year,ComissionLevelID)
Table ClientCommission
{
Year,
ClientID,
CommissionLevelID_1,
CommissionLevelID_2,
... other properties ...
}
primary key (Year,ClientID)
foreign key CommissionLevel1 (Year,CommissionLevelID_1)
foreign key CommissionLevel2 (Year,CommissionLevelID_2)
Actuellement mon mappages sont comme suit:
public ComissionLevelMap()
{
Schema("XXXX");
Table("ComissionLevel");
LazyLoad();
CompositeId()
.KeyProperty(x => x.Year, set => {
set.ColumnName("Year");
set.Access.Property(); } )
.KeyProperty(x => x.CommissionLevelID, set => {
set.ColumnName("CommissionLevelID");
set.Length(10);
set.Access.Property(); } );
HasMany<ClientCommission>(x => x.ClientCommissions)
.Access.Property()
.AsSet()
.Cascade.AllDeleteOrphan()
.LazyLoad()
.Inverse()
.Generic()
.KeyColumns.Add("Year", mapping => mapping.Name("Year")
.SqlType("NUMBER")
.Nullable())
.KeyColumns.Add("CommissionLevelID_1", mapping => mapping.Name("CommissionLevelID_1")
.SqlType("VARCHAR2")
.Nullable()
.Length(10));
HasMany<ClientCommission>(x => x.ClientCommission2s)
.Access.Property()
.AsSet()
.Cascade.AllDeleteOrphan()
.LazyLoad()
.Inverse()
.Generic()
.KeyColumns.Add("Year", mapping => mapping.Name("Year")
.SqlType("NUMBER")
.Nullable())
.KeyColumns.Add("CommissionLevelID_2", mapping => mapping.Name("CommissionLevelID_2")
.SqlType("VARCHAR2")
.Nullable()
.Length(10));
}
public ClientCommissionMap()
{
Schema("XXXXX");
Table("ClientCommission");
LazyLoad();
CompositeId()
.KeyProperty(x => x.ClientID, set => {
set.ColumnName("ClientID");
set.Length(10);
set.Access.Property(); } )
.KeyProperty(x => x.Year, set => {
set.ColumnName("Year");
set.Access.Property(); } );
References(x => x.ComissionLevel1)
.Class<ComissionLevel>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.Insert()
.Update()
.Columns("Year", "CommissionLevelID_1");
References(x => x.ComissionLevel2)
.Class<ComissionLevel>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.Insert()
.Update()
.Columns("Year", "CommissionLevelID_2");
}
Mon problème est maintenant à chaque fois que je créer un CommissionLevel et attribuer ClientCommission à sa collection, si je les enregistrer à l'appel de session.enregistrer(CommissionLevel), il va me jeter une exception
<Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index>.
Ma question ici est:
- Ne NHibernate enregistrer automatiquement les relations? comme:
ClientCommission commission = new ClientCommission{Year = 2012, ClientID =SomeGuid}; CommissionLevel newCommissionLevel = new CommissionLevel{Year = 2012, CommissionLevelID =NewCommissionLevelGuid}; newCommissionLevel.ClientCommission1s.Add(commission); newCommissionLevel.ClientCommission2s.Add(commission); CommissionLevelRepo.Save(newCommissionLevel);
Quand je l'appelle CommissionLevelRepo.Enregistrer(newCommissionLevel), devrait NHibernate sera également mise à jour ClientCommission.ComissionLevel1 Et ClientCommission.ComissionLevel2
ou dois-je dire
ClientCommission.ComissionLevel1 = newCommissionLevel;
ClientCommission.ComissionLevel2 = newCommissionLevel;
- De l'exception que j'ai eu, c'est parce que NHibernate ne génère pas correct de la colonne, il semble qu'il va générer trois Ans de colonnes. Parce que si je créer manuellement les deux propriété appelée ComissionLevelID1 et CommissionLevelID2, désactivez le .Insert() et .Mise à jour() sur ClientCommission il va l'enregistrer correctement.
Quelqu'un peut-il m'indiquer une bonne façon de mapper ces deux classes?
Merci beaucoup.
OriginalL'auteur user1494907 | 2012-07-02
Vous devez vous connecter pour publier un commentaire.
réponse courte: vous ne pouvez pas partager des colonnes pour les multiples références
réponse longue: NHibernate traite chaque référence indépendants les uns des autres, mais ne éliminer les doubles colonnes dans les états d'insertion, d'où les références essayez d'accéder à des colonnes qui ne sont plus réunies. il le fait parce que si cette colonne diffère entre les références dans le modèle d'objet, il ne peut pas décider laquelle est la bonne.
Si vous pouvez modifier le schéma de base de données et de faire de l'id unique, alors ignorer l'année tous ensemble dans les identifiants et les références.
Mise à jour:
vous pouvez simplifier certaines des mappages
la plupart de c'est douloureuse expérience avec les dbs. J'ai découvert les causes par googler, la lecture NH source, d'essai et d'erreur. Chaque fois que vous rencontrez un tel problème, vous devez faire des compromis. Soit la carte différemment (par exemple ignorer les primaires et les clés étrangères dans la db si des pièces sont uniques), saignement de propriétés privées dans le domainmodel, de mettre en œuvre nhibernate crochets pour obtenir autour de la gestion par défaut de NHibernate.
OriginalL'auteur Firo
Pour clé composite, regardez La cartographie des clés Composites dans NHibernate Fluent
Pour simplifier la cartographie, vous pouvez modifier la clé primaire d'une seule touche et de créer un index unique pour le représenter, mais n'est pas la meilleure solution.
Avant (Clé Composite):
Après (Clé Unique avec l'Index Unique):
OriginalL'auteur Andre Mesquita