Having entered the world of NHibernate less than one year ago, I m still developing my "personal" best practice and architectural solutions in this area... now I m facing a pretty simple issue on which I d like to have opinions or suggestions by somebody with more expertise.
情景如下:直接父子关系存储在父节点侧的ISet中。
课程:
public class IDPersisted<IdentifierType>
{
private IdentifierType _id;
public IDPersisted()
{
_id = default(IdentifierType);
}
public IDPersisted(IdentifierType id)
{
_id = id;
}
}
public class SportCenter : IDPersisted<Guid>
{
...
private ISet<Field> _fields = new HashedSet<Field>();
public bool AddField(Field field)
{
field.SportCenter = this;
return _fields.Add(field);
}
public bool RemoveField(Field field)
{
field.SportCenter = null;
return _fields.Remove(field);
}
...
}
public class Field : IDPersisted<Guid>
{
public Field(String name)
{
Name = name;
}
public String Name { get; set; }
public SportCenter SportCenter { get; set; }
...
}
正如您所看到的,我有一个实现泛型标识符、相等/哈希值和==/!=操作符的基类,所有这些都依赖于ID字段,在类实例生命周期中被认为是不可变的。SportCenter(父级)和Filed(子级)类都使用Guid标识符进行持久化。SportCenter保存一个集合(实际上是一个Set)的Field实例,在Add / RemoveField方法中管理双向关系。
映射:
<class name="SportCenter" table="SportCenters" lazy="false">
<id name="ID" column="SportCenterID" >
<generator class="guid.comb" />
</id>
...
<set name="Fields" table="Fields" inverse="true" lazy ="true" cascade="all-delete-orphan" access="field.camelcase-underscore">
<key column="SportCenterID" />
<one-to-many class="Field" />
</set>
</class>
<class name="Field" table="Fields" lazy="false">
<id name="ID" column="FieldID" type="Guid">
<generator class="guid.comb" />
</id>
<property name="Name" column="Name" type="String" not-null="true" />
...
<many-to-one name="SportCenter" column="SportCenterID" class ="SportCenter" not-null="true" lazy="proxy" />
</class>
我已采纳你为测绘这种关系而获得的所有基本建议:反向=“真实”,《一套规则》不能直接获得(进入“现场”)、提单和不发薪。
在我的BLL中,我有一个方法来在特定的运动中心内创建一个新的领域:
public void CreateField(FieldDTO fieldDTO, Guid sportcenterID)
{
// Retrieve the SportCenter
SportCenter sportcenter = SportCentersDAO.GetByID(sportcenterID);
// Prepare the new Field object
Field field = new Field(fieldDTO.Name);
...
// Add the new field to the SportCenter
sportcenter.AddField(field);
// Save the SportCenter
SportCentersDAO.Save(sportcenter);
}
发生的情况是,当我创建新的Field实例时,它的ID被设置为
This breaks one of the rules you can find in every spec/doc/book about NHibernate that is: never change the ID of an instance while it is stored in an ISet (since the ID is the property by which instances are compared by Equals() as I wrote uphere).
在将字段添加到Set之前,为其提供一个GUID值的ID将带我进入邪恶的“分配”ID,并且如果您回答说不要依赖于ID进行Equals/GetHashCode code>并找到自然的与模型相关的关键字...好吧,我不相信我曾经在这些属性中找到过提供不可变性/唯一性所应具备的“键”。
我做错了什么吗?你对此有何看法?
谢谢你事先的帮助,彼得。