Come posso mappare List > in NHibernate?
-
22-09-2019 - |
Domanda
Ho una classe Rotation
, che contiene riferimenti a più liste di oggetti Advert
. Io preferirei un'implementazione in cui Rotation
ha una proprietà di tipo List<List<Advert>>
di tenere questi, ma non sono in grado di elaborare una mappatura NHibernate sostegno di questa.
Nello schema del database, molti-a-molti tra Rotation
e Advert
è rappresentato come un RotationAdvert
tabella con le seguenti colonne:
-
RotationID
-
AdvertID
-
Variant
( "posizione orizzontale" / indice all'interno elenco esterno) -
Position
( "verticale" / indice all'interno lista interno)
La soluzione migliore che ho ancora trovato, è quello di implementare un numero fisso di List<Advert>
digitato immobili in Rotation
ed estendere la mappatura con un elemento per ogni <list>
:
<list name="Variant1" table="RotationAdvert" where="Variant = 1">
<key column="RotationID"/>
<index column="Position"/>
<many-to-many class="Advert" column="AdvertID"/>
</list>
<list name="Variant2" table="RotationAdvert" where="Variant = 2">
<key column="RotationID"/>
<index column="Position"/>
<many-to-many class="Advert" column="AdvertID"/>
</list>
etc...
Tuttavia, questo mi richiede di specificare un numero fisso di varianti, che mi piacerebbe davvero evitare.
Quali sono le altre opzioni? Posso spremere una classe RotationVariant
nel modello - senza creare nuove tabelle nel database - e in qualche modo mappare una proprietà List<RotationVariant>
su Rotation
? Oppure dovrò creare una nuova tabella nel database, solo per tenere un ID per ogni RotationVariant
?
Soluzione
Ho appena imbattuto in questo stesso problema di oggi. Leggendo la documentazione Hibernate e trovato una risposta nella sezione 6.1: Raccolta Mapping https: / /www.hibernate.org/hib_docs/nhibernate/html/collections.html :
Collezioni non possono contenere altre collezioni
non riuscivo a trovare questa frase esatta nella documentazione NHibernate, ma sembra che la stessa regola si applica. Come Stephan e Chris ha detto, si avrà probabilmente bisogno di avere un altro soggetto per contenere i valori.
Altri suggerimenti
Il meglio che posso pensare è di adattare il modello per la struttura del database desiderato.
class Rotation
{
IList<AdvertVariant> AdvertVariants { get; private set; }
}
class AdvertVariant
{
int Variant { get; set; }
Advert Advert { get; set; }
}
mappatura:
<class name="Rotation">
<list name="AdvertVariants" table="RotationAdvert" >
<key column="RotationID"/>
<index column="Position"/>
<one-to-many class="AdvertVariant"/>
</list>
</class>
<class name="AdvertVariant">
<property name="Variant" />
<many-to-one name="Advert" column="VariantId"/>
</class>
Database:
Rotation:
id
AdvertVariant
id
Variant
RotationId
VariantId
Advert
id
Quindi è possibile creare facilmente immobili come questo:
class Rotation
{
//...
IDictionary<int, IList<Adverts>> AdvertsByVariant
{
return VariantAdverts.ToDictionary(x => x.Variant, y => y.Advert);
}
}
Mi piacerebbe proporre di avere una classe di rotazione che contiene un elenco di annunci. Un annuncio poi contiene un elenco di annunci figlio in un relazione genitore-figlio.