2011-02-22 15 views
0

、私は二つの表(グラフ表現 - 1つのテーブルノードで、他のノード間のリンクがある)を持っている、と私はNHibernateは、このクエリ書きたい:私は接続する方法を見つけることができませんでしたNHibernateは結合問合せ

SELECT 
    distinct(t.id), t.NodeName, e.Fk_linkOne, e.Fk_linkTwo, e.RelationName 
FROM Nodes t 
INNER JOIN NodeRelation e ON t.Id=e.Fk_linkOne OR t.Id=e.Fk_linkTwo 
where (e.Fk_linkOne =84 OR e.Fk_linkTwo=84) AND t.Id!=84 

+0

は、あなたが見ることができますマッピングを持っていますか? –

答えて

0

マッピングで定義した関連付けによってのみジョインを定義できます。私が知る限り、NhibernateではORスタイルの関係を定義することはできません。自己参照形式のグラフ表現の使用を検討してください。

public class Node 
{ 
    public IList<Node> Parents { get; set; } 
    public IList<Node> Children { get; set; } 
} 

<bag name="Parents" table="Node_Relation"> 
    <key column="ChildId" /> 
    <many-to-many class="Node" column="ParentId" /> 
</bag> 
<bag name="Children" table="Node_Relation"> 
    <key column="ParentId" /> 
    <many-to-many class="Node" column="ChildId" /> 
</bag> 
+0

これは本当に真実ではありません。 ORを使用していても条件付きではなく、任意のプロパティによって関連付けることができます。 HQLを使用すると、\tのデカルト積を作成し、where句でフィルタリングできます。これは常に内部結合です。 –

0

同じことを行うには、DetachedCriteriaを使用する必要があります。私はあなたの質問については確信していませんが、私はショットを与えるだろう。

var dc1= DetachedCriteria.For(typeof(NodeRelation)).Add(Restrictions.Eq("Fk_linkOne", 84)) 
.SetProjection(Projections.Property("Fk_linkOne")); 

var dc2= DetachedCriteria.For(typeof(NodeRelation)).Add(Restrictions.Eq("Fk_linkTwo", 84)) 
.SetProjection(Projections.Property("Fk_linkTwo")); 

Session.CreateCriteria(typeof(Nodes)) 
.Add(Subqueries.PropertyIn("Id", dc1)) 
.Add(Subqueries.PropertyIn("Id", dc2)) 
.Add(Restrictions.Eq("Id", 84)).List<Nodes>; 

上記のクエリが妥当であることを望みます。私はあなたがそれを得ることができない場合、私に知らせてください。

+0

私はこれについても考えましたが、問題はNodeRelationテーブルから必要なフィールドを与えられないということです。 – Vadim

+0

それから彼は基準のクエリで同じに参加する必要があります.. – Baz1nga

0

いつもあなたのクラスに依存し、あなたのテーブルにはあま​​り依存しません。 ORMを使用しており、クラスモデルで作業していることを覚えておいてください。

class Node 
{ 
    List<Node> Relations { get; private set; } 
    List<Node> InverseRelations { get; private set; } 
} 

あなたはこのようにそれをマッピングすることができる:

<class name="Node"> 
<!-- .... --> 
    <bag name="Relations" table="NodeRelation"> 
    <key name="Fk_linkOne"> 
    <many-to-many class="Node" column="Fk_linkTwo"/> 
    </bag> 
    <bag name="InverseRelations" table="NodeRelation" inverse="true"> 
    <key name="Fk_linkTwo"> 
    <many-to-many class="Node" column="Fk_linkOne"/> 
    </bag> 

</class> 

あなたがasymetrical関係を取得し、この方法は(これが意味:ノードAはノードBに関連したときに、あなたのクラスは次のように見えること想定

、もちろんBのInverseRelationを除いて、Bは必ずAに関連するとは限りません)。私はあなたが実際に必要なものを知らないので、これはあなたのデータベース設計に基づく仮定です。

あなたのクエリは、このように見えるかもしれ

from Node n 
where 
    :x in elements(n.Relations) 
    or :x in elements(n.InverseRelations) 

注:xは、エンティティタイプだけではなく、IDです(あなたがsession.Load<Node>(84)を使用して、それをロードする必要がある)、

SAMYクエリのための別の方法:

select distinct n 
from Node n 
    inner join n.Relations e1 
    inner join n.InverseRelations e2 
where e1.id = 84 or e2.id = 84 

または逆関係を使用することなく、別の方法:

私は第二の溶液を取ると、このようにそれを記述した基準で

session.CreateCriteria<Node>("n") 
    .SetProjection(Projections.Distinct("n")) 
    .CreateCriteria("Relations", "e1") 
    .CreateCriteria("InverseRelations", "e2") 
    .Add(Expression.Or(
    Expression.Eq("e1.id", 84), 
    Expression.Eq("e2.id", 84));