我有两个表(图表表示 - 一个表是节点,另一个是节点之间的链接),我想在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
我没有找到如何通过连接连接两个表,其中包含OR ..
ICriteria criteriaSelect = Session
.CreateCriteria(typeof(NodeRelation ), "nodeRelations")
.CreateCriteria("nodeRelations.Node", "node",
NHibernate.SqlCommand.JoinType.InnerJoin)
答案 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>
答案 1 :(得分: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>;
希望上面的查询是正确的。请告诉我,如果你在尝试涂抹后不能让它工作,请告诉我你试过的。
答案 2 :(得分: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>
这样你就得到了不对称关系(这意味着:当节点A与节点B相关时,B当然不一定与A相关,当然除了InverseRelation)。我不知道你真正需要什么,所以这是基于你的数据库设计的假设。
您的查询可能如下所示:
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
或者不使用反向关系的另一种方式:
select n
from Node n, Node n2 inner join n.Relations e
where
(n = n2 and e.id = 84)
OR (n = e and n2.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));