我有这个查询,我正在运行这些表之间的前期连接:
表 - 列
- 项目 - ID,名称,说明
- ProjectSponsor (桥牌表) - id,sponsorid,projectid,isPrimarySponsor
- 赞助商 - id,first,last
这是我正在运行的nhibernate 3 linq查询:
IEnumerable<Project> list = Session.Query<Project>().FetchMany(r => r.ProjectSponsors).ThenFetch(r => r.Sponsor);
如何添加where子句以仅包含sponsorName =“Joe”
的赞助商我记得看到fetch总是在nhibernate linq查询的结尾处出现但似乎我需要在“ThenFetch”之后执行此操作才能使其工作?
任何人都可以告诉我如何在赞助商上添加“where子句”等同物
由于桥接表中需要“ isPrimarySponsor ”字段,我不能只是从项目到赞助商进行简单的多对多直接映射。
答案 0 :(得分:7)
首先让我展示我对你想要达到的目标的理解。您想要获取所有项目,并希望获取包含赞助商的相应ProjectSponsors,但您只需要具有赞助商特定名称的ProjectSponsors。
因此,如果项目没有“Joe”赞助商,那么其ProjectSponsors集合将为空。是吗?
如果是这样,您希望在项目和赞助商之间进行左联接。此外,您希望一次性获取所有内容,这就是您要使用这些Fetch方法的原因。
据我所知,实际上没有办法在你的陈述中添加Where。但即使有,我认为它也无济于事。如果你能写:
Session.Query<Project>().FetchMany(r => r.ProjectSponsors).ThenFetch(r => r.Sponsor).Where(s => s.Name == "Joe")
它会生成什么样的SQL?像这样:
SELECT
*
FROM
Project P
LEFT JOIN ProjectSponsors PS ON PS.ProjectId = P.ProjectId
LEFT JOIN Sponsors S ON S.SponsorId = PS.SponsorId
WHERE
S.Name = 'Joe'
然而,这将导致仅选择至少有一个名为Joe的赞助商的项目。
实际上,您想要过滤ProjectSponsors,只选择那些赞助商名为Joe的人。
现在我不知道这对你来说是否是一个可以接受的解决方案,但我就是这样做的。我将在Project实体的ProjectSponsors关联映射中定义和设置一个过滤器,如下所示:
<class name="Project" table="Project">
...
<set name="ProjectSponsors" table="ProjectSponsor">
<key column="ProjectId" />
<one-to-many class="ProjectSponsor" />
<filter name="SponsorName" condition="EXISTS (SELECT * FROM Sponsor where Sponsor.SponsorId = SponsorId AND Sponsor.Name=:name)" />
</set>
</class>
<filter-def name="SponsorName">
<filter-param name="name" type="String"/>
</filter-def>
有了这个,我会在启用和设置过滤器后使用原始语句:
Session.EnableFilter("SponsorName").SetParameter("name", "Joe");
var projects = Session.Query<Project>().FetchMany(r => r.ProjectSponsors).ThenFetch(r => r.Sponsor);
这将产生这样的SQL:
SELECT
*
FROM
Project P
LEFT JOIN ProjectSponsors PS ON PS.ProjectId = P.ProjectId AND EXISTS (SELECT * FROM Sponsor where Sponsor.SponsorId = PS.SponsorId AND Sponsor.Name = 'Joe')
LEFT JOIN Sponsors S ON S.SponsorId = PS.SponsorId
将选择所有项目,但仅为他们选择具有Joe作为赞助商的ProjectSponsor组合。
我不确定这是否是最佳方法,但希望它会有所帮助。
答案 1 :(得分:0)
我创建了这样的NHibernate Linq查询:
IEnumerable<Project> list = (
from p in Session.Query<Project>()
from s in p.Sponsors
where s.Name == "SponsorName"
select p)
.FetchMany(r => r.Sponsors)
.ThenFetch(r => r.Sponsor).ToList();