我有一个像这样声明的对象
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);
这可以保存,但现在我的对象有一个空子,这不是我想要的行为。我可以使用的黑客是在创建新的MyObject
后将子项重置为空,但我想看看是否有更好的方法。
Child必须在我的对象中不为null,但如果子对象的ID为0,则保存为null。
修改
只是测试了整个null / reset策略,但它不起作用。对模型中任何对象的后续nhibernate请求会导致瞬态对象错误。
答案 0 :(得分:1)
您希望正常和持久性使用具有不同的行为。你可以实现自己的entitypersistor,但这需要付出很多努力。在这种情况下我更喜欢解决方法,因为这违反了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")
另一种选择是在保存eventlistener之前和之后实现null /重置子对象,但仍然需要付出很多努力。