gpt4 book ai didi

nhibernate - 如何在 nhibernate 中保存分配了 id 的 child

转载 作者:行者123 更新时间:2023-12-03 08:21:00 25 4
gpt4 key购买 nike

我有两个类:

public class Parent
{
public virtual long? ID { get; set; } // native
public virtual IList<Child> Children { get; set; }
public virtual string Name { get; set; }
}

public class Child
{
public virtual long ID { get; set; } // assigned
public virtual string Name { get; set; }
}

实例化和保存 parent 和 child :
child = new Child() { ID = 1, Name = "SomeName" };
parent = new Parent() { Children = new List() { child } };
session.Save(parent);

这给了我:

NHibernate.StaleStateException:意外的行数:0;预期:1。

我认为问题出在 child 的分配ID上。由于它有一个 id,NHibernate 认为它以前保存过,但事实并非如此。

生成的(修剪和重命名的)SQL 是:
NHibernate: select child0_.ID as child1_1_, child0_.NAME as NAME1_, child0_.PARENT_ID as COMMAND7_1_, from CHILD child0_
NHibernate: select parent0_.PARENT_ID as parent1_10_
NHibernate: select parent0_.PARENT_ID as parent1_10_, parent0_.NAME as parent2_10_ from PARENT parent0_
NHibernate: UPDATE CHILD SET PARENT_ID = @p0 WHERE CHILD_ID = @p1;@p0 = 2, @p1 = 1

映射文件:
<class name="MyNamespace.Child" table="CHILD">
<id name="ID" column="CHILD_ID" type="System.Int64">
<generator class="assigned"></generator>
</id>
<property name="Name" column="NAME"></property>
</class>

<class name="MyNamespace.Parent" table="PARENT">
<id name="ID" column="PARENT_ID" type="System.Int64">
<generator class="native"></generator>
</id>
<property name="Name" column="NAME"></property>
<bag name="Children">
<key column="PARENT_ID"></key>
<one-to-many class="MyNamespace.Child"></one-to-many>
</bag>
</class>

在搜索谷歌时,我发现版本标签可能是一个解决方案,但我没有一个持久字段可用作版本。在这种情况下,如何保存(插入)具有指定 ID 的子项及其父项?

最佳答案

我不是 100% 确定这是否与您遇到的问题相同,但我的数据库是 100% 分配的 id(呃),我必须创建一个拦截器来跟踪 child 是否为级联持久化去工作。

代码是剪切/粘贴的(这就是为什么它有愚蠢的名字......一开始我没有 100% 理解!),我最初从在线文档中获得了 90% 的代码(我无法通过谷歌找到正确的现在......对不起):

您放置在具有要级联的分配 ID 的对象上的基类:

public class Persistent
{
private bool _saved = false;

public virtual void OnSave()
{
_saved = true;
}

public virtual void OnLoad()
{
_saved = true;
}

public virtual bool IsSaved
{
get { return _saved; }
}
}

您添加到 session 的拦截器:
public class TrackingNumberInterceptor : EmptyInterceptor
{
public override bool? IsTransient(object entity)
{
if (entity is Persistent)
{
return !((Persistent)entity).IsSaved;
}
else
{
return null;
}
}

public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
if (entity is Persistent) ((Persistent)entity).OnLoad();
return false;
}

public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
if (entity is Persistent) ((Persistent)entity).OnSave();
return false;
}
}

基本上这个想法是,由于 NHibernate 不知道分配的 id 实体是否被持久化,因此您可以跟踪它。

默认情况下,对象以 false 的持久化 (_saved) 开头。当 NHibernate 加载或保存实体时,触发器将对象持久化 (_saved) 标志设置为 true。

因此,对于未持久化的新项目,它从 false 开始并保持为 false,因为 NHibernate 从未保存或加载过它。当 NHibernate 检查 child 是否是 transient 的时,触发器会响应它是 transient 的,并且会发生将 child 标记为持久的保存。此外,现在任何 future 的使用都将需要一个再次将其标记为持久的负载。

关于nhibernate - 如何在 nhibernate 中保存分配了 id 的 child ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1070311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com