为什么NHibernate先删除,然后在select上插入复合元素?
有人能给我解释一下NHibernate是如何处理复合元素的吗 我有这样的课程为什么NHibernate先删除,然后在select上插入复合元素?,nhibernate,Nhibernate,有人能给我解释一下NHibernate是如何处理复合元素的吗 我有这样的课程 public class Blog { public virtual int Id { get; private set; } public virtual ISet<Comment> Comments { get; set; } } public class Comment { pu
public class Blog
{
public virtual int Id
{
get;
private set;
}
public virtual ISet<Comment> Comments
{
get;
set;
}
}
public class Comment
{
public virtual string CommentText
{
get;
set;
}
public virtual DateTime Date
{
get;
set;
}
}
<class name="Blog" table="blog">
<id name="Id" column="id" unsaved-value="0">
<generator class="hilo"/>
</id>
<set name="Comments" table="blog_comments">
<key column="blog_id" />
<composite-element class="Comment">
<property name="CommentText" column="comment" not-null="true" />
<property name="Date" column="date" not-null="true" />
</composite-element>
</set>
</class>
using (ITransaction transaction = session.BeginTransaction())
{
Blog blog = session.CreateCriteria(typeof(Blog))
.SetFetchMode("Comments", FetchMode.Eager)
.Add(Expression.IdEq(2345))
.UniqueResult();
transaction.Commit();
}
NHibernate发出一个带有连接的select以获取包含帖子的博客,但随后删除所有评论,然后插入评论!为什么要这样做?如果我不使用事务,那么它将只执行select,而不是像我预期的那样执行DELETE和INSERT。我错过了什么?我使用的是NHibernate2.0,我的问题是,如果您只需要进行选择,为什么要提交?我认为它删除所有注释的原因是,当您对事务调用commit时,blog对象及其关联的注释会缓存在用于创建事务的会话中。调用提交时,会导致保存会话中的所有对象,从而导致将其保存回数据库。我不清楚为什么要删除注释,但保存对象是正确的行为 我还: NHibernate正在删除我的整个 收集并重新创建它 更新表格的步骤。 这通常发生在NHibernate时 无法确定更改了哪些项目 收藏中。常见的原因有:
- 用新集合实例完全替换持久集合
- 将手动构造的对象传递给NHibernate并对其调用Update
- 序列化/反序列化持久集合显然也会导致此问题
- 使用reverse=“false”更新a”-在这种情况下,NHibernate无法构造SQL来更新单个集合项
- 将从NHibernate获得的同一个集合实例传递回它(不一定在同一个会话中)
- 尝试使用其他集合而不是(或),或
- 请尝试对使用reverse=“true”属性
我认为您需要在注释中重写Equals()和GetHashCode()。NHibernate没有实体相等的ID,因此您必须定义如何使一个注释实体等于另一个注释 可能是错的:)
编辑 从(8.2) 注意:如果定义复合元素的ISet,正确实现Equals()和GetHashCode()是非常重要的 以及(4.3)中实现Equals/GetHashCode的示例
我认为commit只会更新已经更改的实体,因为没有一个实体会更新,为什么它会尝试更新任何东西?我也读了这一页,我同意你不应该使用隐式事务,我只是不清楚如果没有任何更改,为什么你会提交事务。无论如何,我喜欢这个问题,而且答案非常翔实-1因为您应该始终有显式事务,如果没有提交,您会收到警告。谢谢,我在完整版本中实现了这些,但一定是在GetHashCode的重写中出错了,您提供的示例非常有用。再次感谢你。
public class Cat
{
...
public override bool Equals(object other)
{
if (this == other) return true;
Cat cat = other as Cat;
if (cat == null) return false; // null or not a cat
if (Name != cat.Name) return false;
if (!Birthday.Equals(cat.Birthday)) return false;
return true;
}
public override int GetHashCode()
{
unchecked
{
int result;
result = Name.GetHashCode();
result = 29 * result + Birthday.GetHashCode();
return result;
}
}
}