NHibernate 如何将交叉引用表映射到包?

Posted

技术标签:

【中文标题】NHibernate 如何将交叉引用表映射到包?【英文标题】:NHibernate how do you map a cros-s-reference table to a bag? 【发布时间】:2014-04-16 16:44:28 【问题描述】:

我最近在工作中继承了一个包含 NHibernate 的项目。我对它非常陌生,必须对其中一个映射进行修改。我已阅读文档here,但我仍然不确定如何执行此操作,或者我的理解/术语是否正确。

因此,鉴于下表结构,我需要一个可以获取项目名称的包:

User
  UserID (PK)

ProjectUser
  UserID (PK, FK User.UserID)
  ProjectID (PK, FK Project.ProjectID)

Project
  ProjectID (PK)
  ProjectName

这是现有的包映射,它正确返回 ProjectID,但现在我试图了解如何修改它以返回 ProjectID 和 ProjectName:

<bag name="Projects" table="ProjectUser" lazy="true" inverse="true" cascade="save-update">
  <key column="UserId"></key>
  <many-to-many class="Project" column="ProjectID"></many-to-many>
</bag>

【问题讨论】:

当您说“我需要修改它以返回 ProjectID 和 ProjectName”时,您究竟是什么意思?如果您想查看属于特定用户的所有 ProjectName,您只需遍历该用户的项目集合并使用 Project.ProjectName。通常,您上面的关系将由 2 个类 User 和 Project 表示。用户有一个项目集合,项目有一个用户集合。您的示例中的中间表 ProjectUsers 没有映射到它的 C# 类。 是的,你是对的,请在下面的答案中查看我的评论。这是一个项目,基本上是在工作中向我抛出的,因为没有其他人有 MVC 经验,而我有零 NHibernate 经验,所以这主要是对多对多关系如何运作的误解。 【参考方案1】:

好吧,您的映射似乎是正确的,即已经返回 ProjectName。请确保检查对象Project 的映射如下:

<class name="Project" table="Project">
  <id name="Id" column="ProjectID" generator class="native"/> 

  <!-- above as the Id we have mapping for column ProjectId
        below the C# Name will contain the column ProjectName -->

  <property name="Name" column="ProjectName" />

  <!-- related Users to this Project -->
  <bag name="Users" table="ProjectUser" lazy="true" >
    <key column="ProjectID"></key>
    <many-to-many class="User" column="UserID" />
  </bag>

</class>

项目会是这样的

public class Project 

    public virtual int Id  get; set;
    public virtual string Name  get; set;
    public virtual IList<User> Users  get; set;
    ...

所以,有了这个,我们应该能够使用用户:

public class User 

    public virtual IList<Project> Projects  get; set;
    ...

像这样由 NHibernate 映射和加载

user = session.Get<User>(x) // id of searched user

foreach(var project in user.Projects)

  var name = project.Name;
  var id = project.Id;
  ...

注意事项:

many-to-many 的情况下,显然可以/应该在两侧映射&lt;bag&gt; - 项目和用户。但其中只有一个可以拥有inverse="true"。所以在这种情况下Project.Users 没有。

many-to-many 上的 cascade 设置正在(很可能)做与人们预期不同的事情。它与配对表无关,但与该映射的第二端有关。

配对对象的级联是开箱即用的。它不必被映射,实际上它不能被映射或关闭......换句话说,我建议删除那个级联,除非你真的想持久地更改项目,如果你正在使用一些用户。

也检查一下:

23.2. Author/Work 如何在没有多对多的情况下做到这一点......将显式配对对象作为映射实体:Nhibernate: How to represent Many-To-Many relationships with One-to-Many relationships? 或 Am I doing many to many incorrectly when using fluent nhibernate?

【讨论】:

原来从 Project 到 User 的映射是存在的,但它被注释掉了,我对 NHibernate 还不够熟悉,还不明白为什么这很重要。取消注释修复了它,但这带来了为什么它被评论以及为什么用户包在评论后没有改变的问题。 "In case of many-to-many there obviously could/should be &lt;bag&gt; mapping on both sides" 对于一个菜鸟来说不是那么明显。如果我说实话,文档有点压倒性,但我会考虑按照你的链接建议的那样多对一地修改这个! 我知道 NHibernate 的弱点。坏消息是,它不会更好,根本看不到新的发展......但是,是的,请尝试通过现有的文档......如果丢失,请毫不犹豫地提出问题这里。我们,如何在 NHibernate 中幸存下来,将尽力帮助您 ;) ;)

以上是关于NHibernate 如何将交叉引用表映射到包?的主要内容,如果未能解决你的问题,请参考以下文章

来自表 Y 的关联引用了一个未映射的类:Y - C# NHibernate

如何 NHibernate 将多个类映射到同一个表

Fluent nHibernate - 如何在联结表上映射非键列?

将引用作为属性的 Nhibernate 映射值对象

您如何在流利的 nhibernate 中映射和使用连接表?

如何在 Fluent NHibernate 中将一对一关系映射为复合键的一部分