NHibernate Collections
Every NHibernate collection (bag
, set
, map
, list
, etc.) has a key
and something describing the contents of the collection. A couple collection types, list
and map
, also have something that describes the index of the collection.
key
is the foreign key that points back to the entity that owns the collection.
The contents of the collection will be described by one of the following elements:
one-to-many
: the contents of the collection are some kind of entity, and the table for that entity is used as the table for the collection. This implies that the other entity probably has amany-to-one
relationship back to this one. Whether you actually end up including that relationship in your object model is a different matter.many-to-many
: the contents of the collection are an entity, but an intermediate table is used for the collection so that the collection elements can be reused by other collections.element
: the contents of the collection are some kind of simple value type, likeint
,string
, etc. Atable
should be specified for the collection since these value types don't have any particular table they normally live in.composite-element
: Similar toelement
, but here multiple columns are mapped to properties in a component class.
Finally, for the index, your choices are either:
index
: the index is a simple value type, likeint
orstring
. This is the only type of index available forlist
s. On alist
, these values correspond directly to the list's index values,list[0]
,list[1]
, etc., so non-sequential values in this column will result in some null values in the .NET collection.index
has been renamed tolist-index
andmap-key
forlist
s andmap
s respectively. Both the old and new names should work.index-many-to-many
: the index is an entity.index-many-to-many
has been renamed tomap-key-many-to-many
. The old and new names both work.
There may be a few more options available, but these are the most commonly used ones.
Your Dictionary
In your case, Entity3
has a dictionary of Entity2
s, indexed by Entity1
, and separate tables are used to keep track of Entity2
and this collection. This means we need a map
with a map-key-many-to-many
(because the index is an entity) and a many-to-many
(because the contents are an entity but we're using a separate table). In HBM XML this would look like:
<map name="Dict" table="Dict">
<key column="Entity3_ID" />
<map-key-many-to-many class="Entity1" column="Entity1_ID" />
<many-to-many class="Entity2" column="Entity2_ID" />
</map>
You do this in FluentNHibernate with the AsEntityMap
method:
HasManyToMany(x => x.Dict)
.Table("Dict")
.ParentKeyColumn("Entity3_ID")
.AsEntityMap("Entity1_ID", "Entity2_ID");
With mapping by code, I would imagine that something like this...
Map(x => x.Dict,
c =>
{
c.Table("Dict");
c.Key(k => k.Column("Entity3_ID"));
},
i => i.ManyToMany(m => m.Column("Entity1_ID")),
v => v.ManyToMany(m => m.Column("Entity2_ID")));
... would do the trick.
I haven't tested the above mappings, and this is my first attempt at mapping by code, so let me know whether it works or not.