3

私は次の構造を持っていました:

User has many books in his history

これは次のように翻訳されました

class User { ICollection<Book> History }       // C#
User -> UserHistory (UserId, BookId) -> Book   // DB

ここで、履歴に日付を追加して、次のクラス構造を作成します。

class User { ICollection<Read> History }
class Read { Book Book, Date At }

dbスキーマをほとんど変更せずに維持する

User -> UserHistory (UserId, BookId, At) -> Book

ReadにマップしたいのですがUserHistory、質問は次のとおりです。

  1. idのマッピングでは何を使用すればよいReadですか? UserHistory主キーは(UserId, BookId). idNH が機能するには が必要ですか?
  2. UserHistory -> Bookの場合のようですone-to-one。この場合、BookId列名を指定するにはどうすればよいですか? UserHistory列属性が表示されませんone-to-one(列名について明示する理由があります)。
4

2 に答える 2

2

最初のシナリオでは、UserHistory は単なる多対多関係のマッピング テーブルであり、適切なオブジェクトがありませんでした。現在、UserHistory テーブル/Read クラスは別のエンティティであるため、何らかの識別子が必要になります。最も簡単な方法は、主キー ReadId (または UserHistoryId) を UserHistory テーブルに追加することです。

別のキーを追加する必要はなく、UserId と BookId で複合キーを使用できますが、ユーザーは本を複数回読むことができますか? その場合、At 列を複合キーに追加して一意にする必要もあります。これは醜くなり、コレクションを扱うときに他の問題につながるため、価値がありません。

UserHistory と Book の関係は、実際には 1 対 1 ではなく多対 1 です。多くの異なるユーザーが同じ本を読むことができます (また、同じユーザーが同じ本を複数回読むこともあります)。多対一をオブジェクト参照と考えてください。

于 2009-10-20T11:58:20.103 に答える
1

質問 1: いいえ、ID は必要ありません。コンポーネント (または、この場合はリスト内にある複合要素) としてマップできます。

質問 2: ユーザー履歴 -> 本は 1 対 1 ではありません。多くのユーザーが同じ本を時間をかけて読んでいる可能性があるため、多対 1 であり、そのようにマッピングする必要があります。

おそらく不完全なマッピングは次のようになります。

<class name="User">

  <bag name="History" table="UserHistory">
    <key name="UserId">
    <composite-element class="Read">
      <property name="At" />
      <many-to-one name="Book" column="BookId" />
    </composite-element>
  </bag>

one-to-one注:マッピングは忘れてください。これは、同じ主キーを共有する 2 つのテーブルがあり、この方法で実際に 1 対 1 でリンクされている場合に、非常にまれにしか使用されません。ほとんどの場合、many-to-one現実の世界では実際には 1 対 1 であっても、 が必要です。

于 2009-10-20T12:31:09.753 に答える