Adi*_*tor 6 nhibernate queryover
您好StackOverflow用户,
我遇到了这个问题,我有三个QueryOvers,每个QueryOvers返回一个候选ID列表,然后我用它来带来这些候选者.为此,我写了以下代码.
private IQueryOver<CandidateEntity, CandidateEntity> UnionPublicWithPrivateCandidates(
IQueryOver<CandidateEntity, CandidateEntity> publicCandidates,
IQueryOver<CandidateEntity, CandidateEntity> privateCandidate,
IQueryOver<CandidateEntity, CandidateEntity> candidatesByUserRole)
{
return ActiveCandidatesQueryOver.Where(Restrictions.Disjunction()
.Add(Subqueries
.WhereProperty<CandidateEntity>(c => c.Id)
.In((QueryOver<CandidateEntity>)publicCandidates.Select(c => c.Id)))
.Add(Subqueries
.WhereProperty<CandidateEntity>(c => c.Id)
.In((QueryOver<CandidateEntity>)privateCandidate.Select(c => c.Id)))
.Add(Subqueries
.WhereProperty<CandidateEntity>(c => c.Id)
.In((QueryOver<CandidateEntity>)candidatesByUserRole.Select(c => c.Id))));
}
Run Code Online (Sandbox Code Playgroud)
这将返回正确的结果,生成的查询如下所示
SELECT *
FROM Applicants
WHERE IsActive = 1
and (Id in (SELECT Id from **FirstQueryOver**)
**or** Id in (SELECT Id from **SecondQueryOver**)
**or** Id in (SELECT Id from **ThirdQueryOver**))
Run Code Online (Sandbox Code Playgroud)
问题是它使用'或'.因此,查询非常缓慢.
如果相反我写这个:
SELECT *
FROM Applicants
WHERE IsActive = 1
and (Id in (SELECT Id from **FirstQueryOver**
union SELECT Id from **SecondQueryOver**
union SELECT Id from **ThirdQueryOver**))
Run Code Online (Sandbox Code Playgroud)
它几乎立即完成.
您是否知道如何重构代码以获得更好的性能?
谢谢你,阿德里安.
小智 1
我搜索但没有找到任何东西,所以我做了以下黑客:
private IQueryOver<CandidateEntity, CandidateEntity> UnionPublicWithPrivateCandidates(
IQueryOver<CandidateEntity, CandidateEntity> publicCandidates,
IQueryOver<CandidateEntity, CandidateEntity> privateCandidate,
IQueryOver<CandidateEntity, CandidateEntity> candidatesByUserRole)
{
var excludedQueryCandidates = QueryOver
.WithSubquery.WhereNotExists(((QueryOver<CandidateEntity>)publicCandidates.Select(x => x.Id)))
.WithSubquery.WhereNotExists((QueryOver<CandidateEntity>)privateCandidate.Select(x => x.Id))
.WithSubquery.WhereNotExists((QueryOver<CandidateEntity>)candidatesByUserRole.Select(x => x.Id));
return QueryOver.WithSubquery.WhereNotExists((QueryOver<CandidateEntity>) excludedQueryCandidates.Select(Projections.Distinct(Projections.Id())));
}
Run Code Online (Sandbox Code Playgroud)
这不是最好的解决方案,但应该可行。