在特定方案(一对多/一对一)中正确nhibrenate映射
-
22-09-2019 - |
题
我有以下结构:
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
, ,问题是:
- 我应该用作什么
id
在映射中Read
?UserHistory
主要关键是(UserId, BookId)
. 。我需要一个吗id
NH工作? UserHistory -> Book
似乎是one-to-one
。如何指定BookId
列名中的列UserHistory
在这种情况下?我看不到列属性one-to-one
(我有理由明确说明列名称)。
解决方案
在您的第一种情况下,用户史只是一张绘制的绘制表,可以进行多到许多关系,并且没有适当的对象。现在,用户史表/读取类是一个独立的实体,因此它需要某种标识符。最简单的方法是将主键readID(或用户史)添加到用户史表中。
您不必添加单独的密钥,并且可以在用户ID和BookID上使用复合密钥 - 但是用户可以多次阅读书籍吗?假设这样,您还需要将AT列添加到复合键以使其独特。这变得丑陋,并在处理收藏时会导致其他问题,因此这是不值得的。
书籍关系的用户历史实际上是一对一的,而不是一对一的。许多不同的用户可以阅读同一本书(也许同一用户可以不止一次阅读书)。将多对一视为对象参考。
其他提示
问题1:不,您不需要ID,您只能将其映射为组件(在这种情况下,在列表中,在这种情况下)
问题2:用户历史 - >书不是一对一的,许多用户可以随着时间的推移阅读同一本书,因此它是多一对一的,应该映射的。
可能不完整的映射看起来如下:
<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
映射。当您有两个共享相同的主键的表格并且将这种方式链接在一起的方式确实一对一时,很少使用它。在大多数情况下,您需要 many-to-one
, ,即使在现实世界中,它实际上是一对一的。
不隶属于 StackOverflow