【问题标题】:Mapping complex joins in nHibernate在 nHibernate 中映射复杂连接
【发布时间】:2012-09-25 17:37:22
【问题描述】:

我在我的最新项目中使用了 nHibernate,并成功映射了所有基本关系,其中值存在于我正在使用的主表中或通过像复合这样的简单关系。

我遇到困难的地方是如何映射复杂的连接?

例如,我有一个名为 Contact 的实体,每个 contact 都有您常用的属性,如姓名、出生日期、电话...。但我还需要它有一个名为 AccreditationList 的属性,即 @987654324 @。

这是 Contact XML 声明的示例。

<class name="Contact" table="Contact" lazy="true">

    <id name="ID" column="ContactID" type="guid">
      <generator class="guid" />
    </id>

    <property name="FirstName">
      <column name="FirstName" sql-type="nvarchar(500)" not-null="true" />
    </property>

    <property name="LastName">
      <column name="LastName" sql-type="nvarchar(500)" not-null="true" />
    </property>

    <bag name="AccreditationList" lazy="true">    
        //How do I express the relationship here? 
    </bag>

</class>

List&lt;Accreditation&gt; 只能通过这样的一系列连接来确定。

SELECT Accreditation.* FROM CourseEnrolment 
INNER JOIN Course ON Course.CourseID = CourseEnrolment.CourseID
INNER JOIN CourseType ON CourseType.CourseTypeID = Course.CourseTypeID
INNER JOIN Accreditation ON Accreditation.AccreditationID = CourseType.AccreditationID
WHERE CourseEnrolment.ContactID = :ContactID

是通过 nHibernate 在代码中使用 CreateSQLQuery 手动调用 SQL 来完成此操作的唯一方法,或者我可以使用命名查询之类的东西来表达这种关系吗?什么是正确的方法?任何指导将不胜感激。

【问题讨论】:

    标签: c# .net nhibernate nhibernate-mapping


    【解决方案1】:

    我看到了几个选项:

    1. 您可以使用SqlSelectSqlUpdate 等指定用于选择/更新等的任意 SQL 语句。(mapping-by-code 示例;我确信有一个 XML 等效项)

    2. 您可以将您的 SQL 查询映射到 QueryOver 查询,并使用它来初始化您的 Accreditation 集合。类似的东西:

      public Contact GetContact(int id) { var contact = _session.Get(id); contact.AccreditationList = _session.QueryOver<Accreditation>() /* your query here */; return contact; }
      然而!!这种方法有几个缺点-

      • 如果您不使用GetContact 方法,您的集合将无法正确填充。
      • 它不支持查询联系人很容易(首先你必须查询联系人,然后你必须初始化每个联系人的认证列表)。
    3. 您可以将中间实体 (Course) 映射到您的 Contact 实体(如果您不想公开它们,您可以将其作为私有成员),然后是您的 AccreditationList属性将是

    public IEnumerable<Accreditaion> AccreditationList { get { return _courses.SelectMany(course => course.Accreditations); } } 不过,您将无法直接操作ContactAccreditationList

    最好的解决方案是在映射中有类似QueryOverSelect 的选项,但 AFAIK 没有...
    就我个人而言,我会选择第 3 个选项,因为它对我来说似乎是最干净的。

    【讨论】:

      猜你喜欢
      • 2013-01-07
      • 1970-01-01
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-11
      • 2011-02-25
      • 1970-01-01
      相关资源
      最近更新 更多