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.
精彩评论