我正在考虑将nHibernate和实体框架作为可能的orm引入系统。我正在尝试使用nHibernate执行相当于以下SQL的操作:
SELECT
a.Id,
a.Name,
a.Etc,
MAX(CASE WHEN (c.dId IS NOT NULL) THEN 1 ELSE 0 END) As IsLinked
FROM
tA a
INNER JOIN tAB ab ON a.Id = ab.aId
INNER JOIN tB b ON ab.bId = b.Id
LEFT OUTER JOIN tC c ON b.cId = c.Id
AND c.dId = 'x'
WHERE
a.Id = 'y'
GROUP BY
a.Id,
a.Name,
a.Etc,
基本上我想从表tA中进行选择,并检查tA中的条目是否链接到表tC中的数据。两个表之间的链接很复杂:
- tA与tB有多对多的关系(使用表tAB)
- tB与使用外键tB的表tC有一对多的关系。
- tC有外键tC。dId到另一个表tD
使用实体框架代码首先我不能使用包含,因为它不允许过滤,但我可以使用投影,所以我得到一个功能正确的查询使用:
var query = from a in db.As
where a.Id == 'y'
select new
{
a,
IsLinked = a.Bs
.Select(b => b.Cs)
.Select(c => c.Where(n => n.dId == 'x'))
.Select(h => h.Count()).Max() > 0
};
生成的SQL是复杂和缓慢的,但工作。我正在努力实现相同的功能在nHibernate从QueryOver:
开始var query = session.QueryOver<A>().Where(a => a.Id == 'y');
如何创建跨多个/嵌套连接类型(一个是OUTER连接)的等效投影,而无需诉诸HQL?或者我是否最好(因为性能可能很差):
- 进行两个查询(一个检索数据,另一个建立链接)
- 引入封装连接复杂性的视图
谢谢
这个查询应该是等价的,你可以试试吗?
var query = from a in db.As
where a.Id == 'y'
select new
{
a,
IsLinked = a.Bs.SelectMany(b => b.Cs).Any(c => c.dId == 'x')
// or
IsLinked = a.Bs.Any(b => b.Cs.Any(c => c.dId == 'x'))
};