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

发布于 2024-11-25 05:10:24 字数 1065 浏览 1 评论 0 原文

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

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/重置策略,但它不起作用。对模型中任何对象的后续 nhibernate 请求都会导致瞬态对象错误。

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()
{
    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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

圈圈圆圆圈圈 2024-12-02 05:10:24

您希望正常使用和持久使用有不同的行为。您可以实现自己的实体持久化器,但这需要付出很多努力。我更喜欢这种情况下的解决方法,因为这违反了 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")

另一种选择是在保存事件侦听器之前和之后实现,该事件侦听器将子对象设置为空/重置,但仍然需要付出很多努力。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文