2

これらのテーブル間に双方向の関係を持たせるには、どの HBM を作成する必要がBlogありますか? 両方から 試しましたが、次の問題に遭遇しました(おそらく、完全に間違っていたためです):Post

many-to-one

  • オブジェクト グラフを 1 つに挿入するときに一時的な永続性エラーが発生しました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>

必要な DB 構造:

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

非 null にする必要がある場合は、ブログプロパティをPostに追加する必要があります ( 6.4. 1 対多の関連付け の最後の段落を参照) 。

動作するはずのいくつかのマッピングを次に示します。

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

これにより、BlogPostCommentの順に挿入され、次にBlogが更新されてLastCommentIdが設定されます。

CommentでSaveを呼び出す必要があることに注意してください。それ以外は失敗します。

于 2011-03-06T01:15:05.517 に答える