映射nHibernate中的复杂连接

时间:2012-09-25 05:13:53

标签: c# .net nhibernate nhibernate-mapping

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

我遇到的问题是如何映射复杂的连接?

例如,我有一个名为Contact的实体,每个contact都有你常用的属性,如姓名,DOB,电话....但我还需要它有一个名为AccreditationList的属性这将是List<Accreditation>

以下是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<Accreditation>只能通过这样的一系列连接来确定。

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

通过使用CreateSQLQuery在代码中通过nHibernate手动调用SQL来实现此目的是唯一的方法,还是可以使用命名查询之类的方式来表达这种关系?什么是正确的方法?任何指导将不胜感激。

1 个答案:

答案 0 :(得分: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财产将是

  4. public IEnumerable<Accreditaion> AccreditationList { get { return _courses.SelectMany(course => course.Accreditations); } } 但是,您无法直接操纵Contact的{​​{1}}。

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