我必须为Blog
和Post
编写哪些HBM才能在这些表之间建立双向关系?
我试过双方many-to-one
但遇到了以下问题(很可能是因为我做错了):
Session
中插入对象图的瞬态持久性错误。Blog
和Post
表互相引用的外键问题。 注意:我的例子是人为的,请不要争论设计。
设计
的 来源:
public class Blog
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Comment LastComment { get; set; } // last-comment
public virtual IList<Post> Posts { get; set; }
}
public class Post
{
public virtual int Id { get; set; }
public virtual string Content { get; set; }
public virtual IList<Comment> Comments { get; set; }
}
public class Comment
{
public virtual int Id { get; set; }
public virtual string Feedback { get; set; }
public virtual Blog Blog { get; set; } //commented-on
}
的 HBM:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Sample"
namespace="Sample">
<class name="Blog">
<id name="Id">
<generator class="hilo" />
</id>
<property name="Name" />
<!-- How to map Comment? -->
<bag name="Posts">
<key column="BlogId" />
<one-to-many class="Post" />
</bag>
</class>
<class name="Post">
<id name="Id">
<generator class="hilo" />
</id>
<property name="Feedback" />
<bag name="Comments">
<key column="PostId" />
<one-to-many class="Comment" />
</bag>
</class>
<class name="Comment">
<id name="Id">
<generator class="hilo" />
</id>
<property name="Comment" />
<!-- How to map back to Blog? -->
</class>
</hibernate-mapping>
必需的数据库结构:
+------------------------------+
| Blog |
+--------------+---------------+
| Id | int |
| Name | nvarchar(50) |
| LastCommentId| int (null) |
+--------------+---------------+
+------------------------------+
| Post |
+--------------+---------------+
| Id | int |
| BlogId | int |
+--------------+---------------+
+------------------------------+
| Comment |
+--------------+---------------+
| Id | int |
| PostId | int |
| BlogId | int (not-null)|
| Feedback | nvarchar(200) |
+--------------+---------------+
答案 0 :(得分:1)
如果博客属性需要不为空,则需要添加博客属性(请参阅6.4. One-To-Many Associations中的最后一段)
以下是一些应该有效的映射:
<class name="Blog" dynamic-update="true">
<id name="Id">
<generator class="..."/>
</id>
<property name="Name" />
<many-to-one name="LastComment" column="LastCommentId" cascade="all" />
<bag name="Posts" cascade="all" inverse="true">
<key column="BlogId" />
<one-to-many class="Post" />
</bag>
</class>
<class name="Post">
<id name="Id">
<generator class="..."/>
</id>
<property name="Content" />
<many-to-one name="Blog" column="BlogId" />
<bag name="Comments" inverse="true">
<key column="PostId" />
<one-to-many class="Comment" />
</bag>
</class>
<class name="Comment">
<id name="Id">
<generator class="..."/>
</id>
<property name="Feedback" />
<many-to-one name="Blog" column="BlogId" not-null="true" cascade="all" />
</class>
然后您将能够使用以下代码:
using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
var blog = new Blog { Name = "My Blog" };
var post = new Post { Blog = blog, Content = "My First Post" };
var comment = new Comment { Blog = blog, Feedback = "Awesome!" };
blog.LastComment = comment;
blog.Posts = new List<Post> { post };
post.Comments = new List<Comment> { comment };
session.Save(comment);
tx.Commit();
}
这会插入博客,然后是发布,然后是评论,然后将博客更新为设置 LastCommentId 。
请注意,您需要在评论上调用保存;其他任何事情都会失败。