How do I map List<List<EntityClass>> in NHibernate?
I have a Rotation
class, which contains references to multiple lists of Advert
objects. I would prefer an implementation where Rotation
has a property of type List<List<Advert>>
to hold these, but I am unable to come up with an NHibernate mapping 开发者_开发问答supporting this.
In the database schema, the many-to-many relation between Rotation
and Advert
is represented as a table RotationAdvert
with the following columns:
RotationID
AdvertID
Variant
("horizontal position" / index within outer list)Position
("vertical position" / index within inner list)
The best solution I have found yet, is to implement a fixed number of List<Advert>
typed properties on Rotation
and extend the mapping with a <list>
element for each:
<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...
However, this requires me to specify a fixed number of variants, which I really would like to avoid.
What are my other options? Can I squeeze a RotationVariant
class into the model - without creating new tables in the database - and somehow map a List<RotationVariant>
property on Rotation
? Or will I have to create a new table in the database, just to hold an ID for each RotationVariant
?
I just ran into this same problem today. Reading through the Hibernate documentation and found an answer in section 6.1: Collection Mapping https://www.hibernate.org/hib_docs/nhibernate/html/collections.html:
Collections may not contain other collections
I couldn't find this exact sentence in the NHibernate docs, but it seems that the same rule applies. Like Stephan and Chris said, you will probably need to have another entity to hold the values.
The best I can think of is to adapt the model to the desired database structure.
class Rotation
{
IList<AdvertVariant> AdvertVariants { get; private set; }
}
class AdvertVariant
{
int Variant { get; set; }
Advert Advert { get; set; }
}
mapping:
<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
Then you can easily create properties like this:
class Rotation
{
//...
IDictionary<int, IList<Adverts>> AdvertsByVariant
{
return VariantAdverts.ToDictionary(x => x.Variant, y => y.Advert);
}
}
I'd propose to have a Rotation class which holds a list of Adverts. An advert then holds a list of child adverts in a parent child relationship.
精彩评论