开发者

NHibernate. Map 1-many Relationship to Dictionary

Hi I'm trying to map a one-many parent-child relationship in NHibernate using XML mapping. Easy enough if the parent class instances store the collection of children in a list, but I want to use a dictionary. Can anyone point me to an example that shows how to set up th开发者_如何学Gois mapping in XML?

In other words I want my parent class to look like this

public class Parent {

   IDictionary<string, Child> children; // key should be Child.Name

}

It's a standard primary key-foreign key relationship in the database. The Child table has Name column which should be mapped to the dictionary key.

Thanks


This certainly is possible. The Hibernate (not NHibernate) documentation does a good job of explaining this. 7.3.3. Bidirectional associations with indexed collections. There is an issue in the NHibernate bug tracker to have this error in the documentation corrected: NH-3554

Below is a complete example of how to do this...

Example

Entity Classes

public class Parent
{
    public virtual int Id { get; private set; }

    private IDictionary<string, Child> _children = new Dictionary<string, Child>();
    public virtual IDictionary<string, Child> Children
    {
        get { return _children; }
        private set { _children = value; }
    }

    public virtual void AddChild(Child child)
    {
        child.Parent = this;
        _children[child.Name] = child;
    }
}

public class Child
{
    public virtual int Id { get; private set; }
    public virtual Parent Parent { get; protected internal set; }
    public virtual string Name { get; set; }
}

NHibernate Mappings

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="so" namespace="so.Q3398624">
  <class name="Parent">
    <id name="Id">
      <column name="Id" />
      <generator class="hilo" />
    </id>
    <map name="Children" inverse="true" cascade="all-delete-orphan">
      <key column="ParentId" />
      <index column="Name" type="string" />
      <one-to-many class="Child" />
    </map>
  </class>
  <class name="Child">
    <id name="Id">
      <column name="Id" />
      <generator class="hilo" />
    </id>
    <many-to-one name="Parent" column="ParentId" cascade="save-update" not-null="true" unique-key="U1" />
    <property name="Name" not-null="true" unique-key="U1" />
  </class>
</hibernate-mapping>

Tables

CREATE TABLE dbo.Parent (
    Id int NOT NULL PRIMARY KEY
);

CREATE TABLE dbo.Child (
    Id int NOT NULL PRIMARY KEY,
    ParentId int NOT NULL,
    Name nvarchar(255) NOT NULL,
    FOREIGN KEY (ParentId) REFERENCES dbo.Parent (Id),
    UNIQUE (ParentId, Name)
);

Insert some records...

var parent = new Parent();
parent.AddChild(new Child { Name = "abc" });
parent.AddChild(new Child { Name = "123" });

session.Save(parent);

Final Notes

Be careful when changing a Child's Name. I think the best approach would be to remove the Child from the Parent, change its name, and finally re-add it to the parent. Otherwise Child.Name and Parent.Children.Keys would be out of sync.


Child.Name can't be both a property and the dictionary key.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜