开发者

Empty Child in model, Null when saved with References<>

开发者 https://www.devze.com 2023-03-21 03:51 出处:网络
I have an object declared like this public class MyObject { public virtual long MyId { get; set; } public virtual MyChild Child { get; set; }

I have an object declared like this

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; }
}

I am setting the child with an "empty object" because I want an empty object instead of a null in my model.

In my database I have a table like this

CREATE TABLE MyObjects
(
    MyObjectId    bigint    IDENTITY(1,1) NOT NULL,
    ChildId       bigint    NULL
)

And then I have in my mapping

References<MyChild>(x => x.Child, "ChildId");

Here's where the problems set in. When I try to create a new MyObject, I will get an error object references an unsaved transient instance. So, I did this:

var newObject = new MyObject()
{
开发者_如何学C    Child = null
};

repository.Save(newObject);

This works to save, but now my object has a null child, which isn't the behavior I want. The hack I could use is to reset the child to empty after creating the new MyObject, but I want to see if there is a better way.

Child needs to be not null in my object, but saved as null if the ID of the child object is 0.

EDIT

Was just testing out the whole null/reset strategy and it doesn't work. subsequent nhibernate requests to any objects in my model cause the transient object error.


You want to have different behavior for normal and persistence use. You could implement your own entitypersistor, but this would require a lot of effort. I prefer workarounds in such situations, because this violates the assumtions NHibernate has.

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")

another option would be to implement before and after save eventlistener which null/resets the child object, but still a lot of effort.

0

精彩评论

暂无评论...
验证码 换一张
取 消