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.