2

我必须为哪些 HBM 编写BlogPost在这些表之间建立双向关系?

many-to-one从双方都尝试过,但遇到了以下问题(很可能是因为我做错了):

  • 将对象图插入到一个中的瞬态持久性错误Session
  • BlogPost表相互引用的外键问题。

注意:我的例子是人为的,请不要争论设计。

设计:

设计


来源:

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) |
+--------------+---------------+
4

1 回答 1

1

如果需要不为空,则需要将Blog属性添加到Post 参见6.4 中的最后一段。一对多关联

以下是一些应该起作用的映射:

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

这会插入Blog,然后是Post,然后是Comment,然后更新Blog以设置LastCommentId

请注意,您需要在Comment上调用Save;其他任何事情都会失败。

于 2011-03-06T01:15:05.517 回答