模型中的空子项,使用引用<>保存时为空

时间:2011-07-19 15:06:42

标签: c# fluent-nhibernate reference fluent-nhibernate-mapping

我有一个像这样声明的对象

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请求会导致瞬态对象错误。

1 个答案:

答案 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 /重置子对象,但仍然需要付出很多努力。