How to map an IDictionary<String, CustomCollectionType> in NHibernate

Posted by devonlazarus on Stack Overflow See other posts from Stack Overflow or by devonlazarus
Published on 2010-05-18T23:00:43Z Indexed on 2010/05/19 14:20 UTC
Read the original article Hit count: 374

Very close to what I'm trying to do but not quite the answer I think I'm looking for:
How to map IDictionary<string, Entity> in Fluent NHibernate

I'm trying to implement an IDictionary<String, IList<MyEntity>>and map this collection to the database using NHibernate. I do understand that you cannot map collections of collections directly in NHibernate, but I do need the functionality of accessing an ordered list of elements by key.

I've implemented IUserCollectionType for my IList<MyEntity> so that I can use IDictionary<String, MyCustomCollectionType> but am struggling with how to get the map to work as I'd like.

Details

This is the database I'm trying to model:

                        ------------------------
--------------------    | EntityAttributes     |
| Entities         |    ------------------------    ------------------
--------------------    | EntityAttributeId PK |    | Attributes     |
| EntityId  PK     | <- | EntityId FK          |    ------------------
| DateCreated      |    | AttributeId  FK      | -> | AttributeId PK |
--------------------    | AttributeValue       |    | AttributeName  |
                        ------------------------    ------------------ 

Here are my domain classes:

public class Entity
{
    public virtual Int32 Id { get; private set; }
    public virtual DateTime DateCreated { get; private set; }

    ...
}

public class EavEntity : Entity
{
    public virtual IDictionary<String, EavEntityAttributeList> Attributes
    {
        get;
        protected set;
    }

    ...
}

public class EavAttribute : Entity
{
    public virtual String Name { get; set; }

    ...
}

public class EavEntityAttribute : Entity
{
    public virtual EavEntity EavEntity { get; private set; }
    public virtual EavAttribute EavAttribute { get; private set; }
    public virtual Object AttributeValue { get; set; }

    ...
}

public class EavEntityAttributeList : List<EavEntityAttribute>
{
}

I've also implemented the NH-specific custom collection classes IUserCollectionType and PersistentList

And here is my mapping so far:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" ...>
    <class xmlns="urn:nhibernate-mapping-2.2" name="EavEntity" table="Entities">

        <id name="Id" type="System.Int32">
            <column name="EntityId" />
            <generator class="identity" />
        </id>

        ...

        <map
            cascade="all-delete-orphan"
            collection-type="EavEntityAttributeListType"
            name="EntityAttributes">

            <key>
                <column name="EntityId" />
            </key>
            <index type="System.String">
                <column name="Name" />
            </index>
            <one-to-many class="EavEntityAttributeList" />
        </map>

    </class>
</hibernate-mapping>

I know the <map> tag is partially correct, but I'm not sure how to get NH to utilize my IUserCollectionType to persist the model to the database.

What I'd like to see (and this isn't right, I know) is something like:

        <map
            cascade="all-delete-orphan"
            collection-type="EavEntityAttributeListType"
            name="EntityAttributes">

            <key>
                <column name="EntityId" />
            </key>
            <index type="System.String">
                <column name="Name" />
            </index>
            <list>
                <index column="DisplayOrder">
                <one-to-many class="EntityAttributes">
            </list>
        </map>

Does anyone have any suggestions on how to properly map that IDictionary<String, EavEntityAttributeList> collection?

I am using Fluent NH so I'll take examples using that library, but I'm hand mappings are just as helpful here.

© Stack Overflow or respective owner

Related posts about nhibernate-mapping

Related posts about nhibernate