Reputation: 105
I am trying to do a join on a subquery to another table I have the following entity:
public class SomeClass
{
public virtual string KeyPart1 { get; set; }
public virtual string KeyPart2 { get; set; }
public virtual int VersionNo { get; set; }
public virtual string ClassProperty1 { get; set; }
public virtual string ClassProperty2 { get; set; }
}
I then have the following query to get me the latest version of each record:
var subquery = QueryOver.Of<SomeClass>()
.SelectList(lst => lst
.SelectGroup(f => f.KeyPart1)
.SelectGroup(f => f.KeyPart2)
.SelectMax(f => f.VersionNo));
I am now trying to return the entire SomeClass for each of the results of the subquery. So far I have something like this:
var query = QueryOver.Of<SomeClass>()
.WithSubquery.Where(???)
The SQL statement should look something like this when it is done
SELECT cls.*
FROM SomeClass as cls
INNER JOIN
(SELECT KeyPart1, KeyPart2, MAX(VersionNo)
FROM SomeClass
GROUP BY KeyPart1, KeyPart2) as sub
ON sub.KeyPart1 = cls.KeyPart1 and sub.KeyPart2 = cls.KeyPart2 and sub.VersionNo = cls.VersionNo
Can someone help me return the entire SomeClass record for each highest version?
EDIT: Can the same thing be done using an exist statement? This will allow us to use something like:
SomeClass classAlias = null
var subquery = QueryOver.Of<SomeClass>()
.SelectList(lst => lst
.SelectGroup(f => f.KeyPart1)
.SelectGroup(f => f.KeyPart2)
.SelectMax(f => f.VersionNo))
.Where(x => x.KeyPart1 == classAlias.KeyPart1)
.Where(x => x.KeyPart2 == classAlias.KeyPart2)
.Where(x => x.VersionNo == classAlias.VersionNo)
var query = Session.QueryOver(() => classAlias)
.WithSubQuery.WhereExists(subquery);
Which generates the following SQL statement:
SELECT *
FROM SomeClass cls
WHERE EXISTS
(SELECT KeyPart1, KeyPart2, MAX(VersionNo)
FROM SomeClass cls2
WHERE cls.KeyPart1 = cls2.KeyPart1 and cls.KeyPart2 = cls2.KeyPart2 and cls.VersionNo = cls2.VersionNo
GROUP BY KeyPart1, KeyPart2)
This however also brings back all versions, but I thought it would be another good place to start.
Upvotes: 0
Views: 1460
Reputation: 105
After a lot of trial and error I was able to get this working using WHERE NOT EXISTS. Hopefully this will help people with a similar problem.
Here is the code snippet that will return the latest version of a particular record using QueryOver:
SomeClass classAlias = null
var subquery = QueryOver.Of<SomeClass>()
.SelectList(lst => lst
.SelectGroup(f => f.KeyPart1)
.SelectGroup(f => f.KeyPart2)
.SelectMax(f => f.VersionNo))
.Where(x => x.KeyPart1 == classAlias.KeyPart1)
.Where(x => x.KeyPart2 == classAlias.KeyPart2)
.Where(x => x.VersionNo > classAlias.VersionNo);
var query = Session.QueryOver(() => classAlias)
.WithSubQuery.WhereNotExists(subquery);
var results = query.List();
Upvotes: 1