模型中的子节点为空,使用References<>保存时为空
本文关键字:保存 References 子节点 模型 使用 | 更新日期: 2023-09-27 18:02:27
我有一个像这样声明的对象
public class MyObject
{
public virtual long MyId { get; set; }
public virtual MyChild Child { get; set; }
public MyObject()
{
Child = new MyChild();
}
}
public class MyChild
{
public virtual long MyId { get; set; }
}
我将子对象设置为"空对象",因为我想要一个空对象而不是模型中的null。
在我的数据库中,我有一个这样的表
CREATE TABLE MyObjects
(
MyObjectId bigint IDENTITY(1,1) NOT NULL,
ChildId bigint NULL
)
然后在我的映射中有
References<MyChild>(x => x.Child, "ChildId");
这就是问题所在。当我尝试创建一个新的MyObject
时,我会得到一个错误对象引用了一个未保存的瞬态实例。所以,我这样做:
var newObject = new MyObject()
{
Child = null
};
repository.Save(newObject);
这可以保存,但现在我的对象有一个空子,这不是我想要的行为。我可以使用的hack是在创建新的MyObject
后将子节点重置为空,但我想看看是否有更好的方法。
Child需要在my object中不为空,但如果子对象的ID为0,则保存为空。
编辑
我只是测试了整个null/reset策略,它不起作用。对模型中任何对象的后续非hibernate请求都会导致暂态对象错误。
对于正常使用和持久使用,您希望具有不同的行为。您可以实现自己的实体持久化,但这将需要大量的工作。在这种情况下,我更喜欢变通方法,因为这违反了NHibernate的假设。
public class MyObject
{
public virtual long MyId { get; set; }
public virtual MyChild Child { get; set; }
protected /*internal*/ virtual MyChild ChildForPersisting
{
get { return (MyChild.Id == 0) ? null : Child; }
set { if (value != null) Child = value; }
}
public MyObject()
{
Child = new MyChild();
}
}
// with internal
References(x => x.ChildForPersisting, "ChildId")
// without internal
References(Reveal.Member<MyChild>("ChildForPersisting"), "ChildId")
另一个选项是在save eventlistener之前和之后实现它为空/重置子对象,但仍然需要很多努力。