代码之家  ›  专栏  ›  技术社区  ›  wizzardz Nikhil

NHinerbate查询问题-使用非主键联接查询

  •  1
  • wizzardz Nikhil  · 技术社区  · 14 年前

    我是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 ....
    }
    

    我没有在Table1类中使用类Table2的实例。

    谢谢,
    亚历克斯

    2 回复  |  直到 14 年前
        1
  •  3
  •   Stefan Steinegger    14 年前

    在HQL中,不加入“tables”。在第一个类上启动查询并导航到属性。

    例如:

    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 指定指向非主键的链接。

        2
  •  0
  •   wizzardz Nikhil    14 年前

    多谢斯特凡,我终于解决了这个问题。

    我将尝试用另一个例子来模拟这个问题。希望这个例子对其他人有用。

    问题:假设我有两个表Employee和Project,Project表有两列'Lead'和'Manager',这两列将存储员工代码。我必须根据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";