针对特定场景的正确 NHibernate 映射(一对多/一对一)
我有以下结构:
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 }
并保持数据库模式几乎不变
User -> UserHistory (UserId, BookId, At) -> Book
我想将 Read
映射到 UserHistory
,问题是:
- 在
Read
映射中我应该使用什么作为id
?UserHistory
主键是(UserId, BookId)
。我需要id
才能让 NH 工作吗? 用户历史记录 -> Book
似乎是一个一对一
的情况。 在这种情况下,如何指定UserHistory
中的BookId
列名称? 我在one-to-one
上没有看到列属性(并且我有理由明确列名)。
I had a following structure:
User has many books in his history
which was translated to the following
class User { ICollection<Book> History } // C#
User -> UserHistory (UserId, BookId) -> Book // DB
Now I want to add a date to the history, creating the following class structure:
class User { ICollection<Read> History }
class Read { Book Book, Date At }
and keeping db schema almost unchanged
User -> UserHistory (UserId, BookId, At) -> Book
I want to map Read
to UserHistory
, the questions are:
- What should I use as
id
in mapping ofRead
?UserHistory
primary key is(UserId, BookId)
. Do I need anid
for NH to work? UserHistory -> Book
seems to be a case ofone-to-one
.
How to specify theBookId
column name inUserHistory
in this case?
I do not see a column attribute onone-to-one
(and there is a reason for me to be explicit about column name).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的第一个场景中,UserHistory 只是一个多对多关系的映射表,并且没有适当的对象。现在,UserHistory 表/Read 类是一个单独的实体,因此它需要某种标识符。最简单的方法是向 UserHistory 表添加主键 ReadId(或 UserHistoryId)。
您不必添加单独的键,并且可以在 UserId 和 BookId 上使用复合键 - 但用户可以多次阅读一本书吗?假设是这样,那么您还需要将 At 列添加到组合键以使其唯一。这会变得丑陋,并且在处理集合时会导致其他问题,所以这是不值得的。
UserHistory 到 Book 的关系实际上是多对一而不是一对一。许多不同的用户可以阅读同一本书(也许同一用户可以多次阅读一本书)。将多对一视为对象引用。
In your first scenario, the UserHistory was simply a mapping table for a many-to-many relationship and didn't have a proper object. Now, the UserHistory table/Read class is a separate entity so it will need an identifier of some sort. The easiest way is to add a primary key ReadId (or UserHistoryId) to the UserHistory table.
You don't have to add a separate key and could use a composite key on UserId and BookId -- but can a user read a book more than once? Assuming so, then you would also need to add the At column to the composite key to make it unique. This gets ugly and will lead to other issues when dealing with collections, so it isn't worth it.
The UserHistory to Book relationship is actually a many-to-one rather than a one-to-one. Many different users can read the same book (and perhaps the same user can read a book more than once). Think of many-to-one as an object reference.
问题 1:不,您不需要 id,您只需将其映射为组件(在本例中为复合元素,它位于列表中)
问题 2:用户历史记录 ->书不是一对一的,许多用户可能随着时间的推移阅读同一本书,因此它是多对一的,应该如此映射。
可能不完整的映射如下所示:
注意:忘记
一对一
映射。当您有两个共享相同主键的表并且通过这种方式真正一对一链接在一起时,这种情况很少使用。在大多数情况下,您需要多对一
,即使在现实世界中它实际上是一对一的。Question 1: no, you don't need an id, you just can map it as component (or composite-element in this case, where it is in a list)
Question 2: User-history -> book is not one-to-one, many users could have read the same book over time, so it's many-to-one and should be mapped so.
Probably incomplete mapping looks as following:
Note: Forget about
one-to-one
mappings. This is used very very rarely, when you have two tables which share the same primary key and are this way linked together really one-to-one. In most cases, you needmany-to-one
, even if in the real world it is actually one-to-one.