2010-11-22 7 views
1

私はNhibernateの新機能です。プロジェクトでnhibernateを使用しようとしていて、次のSQLクエリをNhibernate HQLに変換したいのですか?このクエリはNhibernate HQL/ICriteriaで可能ですか?NHinerbateクエリの問題 - 非プライマリのクエリに参加

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 

これは私が試したものですとfailed.Iは参加のために期待される例外パスを取得しています!

[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クラスのインスタンスを使用しませんでした。

おかげで、HQLで
アレックス

+0

HQLクエリで "a"と "e"とは何ですか? –

+0

よく間違っていました(私の製造コードのものでしたが、今削除されています) – wizzardz

答えて

0

ステファンありがとうございました。ついにこの問題を解決することができました。

私は別の例を使用して問題をエミュレートしようとします。これは他の人にとって役に立ちそうですか?

問題:私は、2つのテーブルEmployeeとProjectがあり、プロジェクトテーブルにEmployeeコードを格納する2つのカラム「Lead」と「Manager」があるとします。マネージャの従業員コードに基づいてプロジェクトの詳細を取得しなければなりませんでした。鉛。

ここに私の問題の解決策があります。
従業員マッピングファイル。

<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> 

Employeeクラス

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"; 
3

は、あなたが "表" に参加しません。最初のクラスでクエリを開始し、プロパティに移動します。例えば

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

その後、非プライマリキーへのリンクを指定するためにproperty-refを使用してmany-to-oneとしてそれをマップします。

+0

こんにちはStefan、返信いただきありがとうございます。私は使用したクラスのサンプルモデルを追加しました。 – wizzardz

+0

表Aと表Bの間に物理的な関係はないが、クラスAのクラスBのインスタンスを持つ必要があるか? – wizzardz

+0

制約のあるFKが存在しない場合でも、マッピングに存在するGuidではなく、Id2というプロパティをTable2クラスにマップする必要があります。 NHの背後にあるアイデアは、あなたが知っている唯一のものはドメインであり、HQLではグラフを表現的にトラバースし、NHはこれを実際のSQLに変換します。したがって、Table1のプロパティId2がTable2のIdを表し、ドメイン内でTable2をトラバースする場合は、そのプロパティをTable2タイプのオブジェクトとしてマップする必要があります。 – Jaguar