Проблема NHinerbate Query - объединение запросов с неосновными ключами - PullRequest
1 голос
/ 22 ноября 2010

Я новичок в Nhibernate, я пытаюсь использовать nhibernate в проекте, и я хотел преобразовать следующий SQL-запрос в Nhibernate HQL?Возможен ли этот запрос в Nhibernate HQL / ICriteria?

SELECT     dbo.Table1.*
FROM         dbo.Table1 INNER JOIN
             dbo.Table2 ON dbo.Table1.Id2 = Table2.Id INNER JOIN
            dbo.Table2 AS T2 ON dbo.Table1.Id3 = T2.Id

Это то, что я пытался и не смог. Я получаю исключение Ожидается путь для соединения!

[from Table1 T1 inner join Table2 T2 inner join Table2 T3 where T1.Id2 = T2.Id and
          T1.Id3 = T3.Id]

Любая помощь будет оценена.

Редактировать 1: Добавление классов, которые я использую.

 public class Table1
{
  public virtual long Id {get;set;}
  public virtual Guid Id2 {get;set}
  public virtual Guid Id3 {get;set}

  other properties ....
}

public class Table2
{
  public virtual long primaryKey {get;set;}
  public virtual Guid Id {get;set;}

  other properties ....
}

Я не использовал экземпляр класса Table2 в классе Table1.

Спасибо,
Алекс

Ответы [ 2 ]

3 голосов
/ 22 ноября 2010

В HQL вы не объединяете "таблицы". Вы запускаете запрос в первом классе и переходите к свойствам.

например:

class A
{
  B MyB { get; set; }
}

class B
{
}

HQL:

SELECT a FROM A a join MyB

MyB - это имя свойства.

Чтобы показать вам фактический запрос для вашего случая, мне нужно знать классы, для которых вы хотите написать запрос.

Это может выглядеть примерно так:

SELECT t1
FROM T1 t1
   join MyT2 t2

Редактировать

Запрос к вашим классам будет выглядеть так:

SELECT t1
FROM Table1 t1, Table2 t2
WHERE t1.Id2 = t2.Id

Нет объединения, потому что в модели нет отношения. Вы можете присоединиться к нему только по кросс-продукту и предложению where.

Вы не получаете большой пользы от NH, если не работаете с полезной моделью класса. Полезный означает, что вы можете перемещаться по модели, не обращаясь к базе данных все время. Когда вы просто пишете классы, которые выглядят как таблицы базы данных, вы не получите много пользы.

Ваши занятия могут выглядеть так:

public class Class1
{
  public virtual long Id {get;set;}
  public virtual Class2 Class2 {get;set}

  other properties ....
}

public class Class2
{
  public virtual long primaryKey {get;set;}
  public virtual Guid Id {get;set;}

  other properties ....
}

Затем вы отображаете его как many-to-one, используя property-ref, чтобы указать ссылку на не первичный ключ.

0 голосов
/ 06 декабря 2010

Большое спасибо, Стефан, наконец-то я смог решить эту проблему.

Я попытаюсь эмулировать проблему, используя другой пример. Надеюсь, этот может пригодиться кому-то еще.

Проблема: скажем, у меня есть две таблицы Employee и Project, в таблице проекта есть два столбца «Lead» и «Manager», в которых будет храниться код «Employee». Мне нужно было получить детали проекта на основе кода «Manager» и «Lead».

Вот решение моей проблемы.
Файл сопоставления сотрудников.

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
       namespace="Learn.Models" assembly="Learn.Models">
  <class name="Employee" table="Employee">
    <id column="Id" type="Int64">
      <generator class="identity"></generator>
    </id>
    <property name="EntityId" column="EmployeeEntityId" not-null="true"></property>
    <property name="FirstName" column="FirstName" not-null="true"></property>
    <property name="LastName" column="LastName" not-null="true"></property>
    <property name="DateOfBirth" column="DateOfBirth" not-null="true"></property>
    <property name="EmpCode" column="EmpCode" not-null="true"></property>
  </class>
</hibernate-mapping>

Файл сопоставления проекта :

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
       namespace="Learn.Models" assembly="Learn.Models">
  <class name="Project" table="Project">
    <id column="Id" type="Int64">
      <generator class="identity"></generator>
    </id>
    <property name="EntityId" column="ProjectEntityId" not-null="true"></property>
    <property name="ProjectName" column="ProjName" not-null="true"></property>

    <many-to-one name="ProjectManager" class="Employee" property-ref="EmpCode" column="Manager" lazy="proxy"></many-to-one>
    <many-to-one name="ProjectLead" class="Employee" property-ref="EmpCode" column="Lead" lazy="proxy"></many-to-one>
  </class>
</hibernate-mapping>

Класс сотрудника :

public class Employee : IEntity
{
    public Employee()
    {
    }

    public virtual long Id { get; set; }
    public virtual Guid EntityId { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual DateTime DateOfBirth { get; set; }
    public virtual string EmpCode { get; set; }
}

Класс проекта :

public class Project:IEntity
{
    public virtual string ProjectName { get; set; }

    public virtual Employee ProjectLead { get; set; }
    public virtual Employee ProjectManager { get; set; }

    public virtual long Id { get; set; }
    public virtual Guid EntityId { get; set; }

}

Мне нужно было получить детали проекта на основена код сотрудника ProjectLead и ProjectManager, и это HQL-запрос, который я использовал.

string hql = "select p from Project p "
                + "join p.ProjectLead as lead "
                + "join p.ProjectManager as manager "
                + "where p.ProjectLead.EmpCode = 006 and "
                + "p.ProjectManager.EmpCode = 005";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...