我有两个实体:
public class Parent()
{
public ICollection<Child> Children { get; set; }
}
public class Child()
{
public Parent Parent { get; set; }
}
映射如下:
public class ParentMap : ClassMap<Parent>
{
HasMany(x => x.Children).Cascade.All().Inverse();
}
public class ChildMap : ClassMap<Child>
{
References(x => x.Parent).Cascade.None();
}
通常,为了保存父母或孩子,你必须做这样的事情:
var parent = new Parent();
var child = new Child();
parent.Children.Add(child);
child.Parent = parent;
Session.SaveOrUpdate(parent);
换句话说,您必须在两个对象中设置属性,以便NHibernate正确地保留此实体。
但是,对于遗留问题,我想保存此实体而不必设置双方,以便我可以这样做:
var parent = new Parent();
var child = new Child();
child.Parent = parent;
Session.SaveOrUpdate(child);
在这种情况下,我不会将子项添加到父项的Children
集合中,我只是在子项对象上设置Parent
。
有没有什么方法可以让NHibernate正确地保持这种状态,这样当我从数据库中抓取父项时,它会将子项放在其Children
集合中?
P.S。我意识到会话缓存存在一个潜在的问题,并依赖NHibernate执行一些幕后操作以使数据模型正确,但我现在忽略了这个问题。
答案 0 :(得分:2)
将Parent映射为Child中的私有字段:
public class ChildMap : ClassMap<Child>
{
References(x => x.Parent).Cascade.None()
.Access.CamelCaseField(Prefix.Underscore);
}
并通过公共财产控制它:
public class Child()
{
private Parent _parent;
public Parent Parent
{
get { return _parent; }
set
{
_parent = value;
_parent.Children.Add(this);
}
}
}
但是您现在拥有的代码应该按预期工作。您不必将Child添加到Parent的Children集合中以使NH保持它,因为它被标记为关系的反面。您添加它以保持内存中的对象与数据库同步。如果在子项上设置Parent,则刷新会话,并在新会话中重新加载父项,然后Children集合应包含子项(假设二级缓存不起作用)。
编辑:要将子项添加到父项,请将操作封装在方法中:
public void AddChild(Child child)
{
_children.Add(child);
child.Parent = this;
}