Mateusz
Mateusz

Reputation: 116

Distinct over one column with value comparing on another column ICriteria NHibernate

I have table and object called Person. I have problem to create a distinct (over column "lastname") criteria. I want to get only the oldest Person with distinct lastnames. For example i have (properties: firstname, lastname, age):

Can anybody help me to create criteria which result i get Person object with John Smith and Brad Pit?

Upvotes: 0

Views: 353

Answers (1)

connectedsoftware
connectedsoftware

Reputation: 7097

Probably the best approach here is to use EXISTS to filter the result set, first a SQL example to get the logic correct:

DECLARE @Person TABLE (
   Id INT,
   Firstname VARCHAR(20),
   Lastname VARCHAR(20),
   Age INT 
)

INSERT INTO @Person VALUES (1, 'Brad', 'Pitt', 42)
INSERT INTO @Person VALUES (2, 'Angelina', 'Pitt', 45)
INSERT INTO @Person VALUES (3, 'John', 'Smith', 50)
INSERT INTO @Person VALUES (4, 'Jane', 'Smith', 55)

SELECT P.* FROM @Person P
WHERE EXISTS(
    SELECT SUB.LastName, MAX(SUB.Age) as Age FROM @Person SUB
    GROUP BY SUB.LastName
    HAVING SUB.LastName = P.LastName AND MAX(SUB.Age) = P.Age)

This yields the following results which is as expected:

Id  Firstname   Lastname    Age
-------------------------------
2   Angelina    Pitt        45
4   Jane        Smith       55

Now to convert to nHibernate, this effectively builds the same query as above:

var subQuery = DetachedCriteria.For<Person>("SUB")
    .SetProjection(Projections.ProjectionList()
    .Add(Projections.GroupProperty("LastName"), "Lastname")
    .Add(Projections.Max("Age"), "Age"))
    .Add(Restrictions.EqProperty(Projections.Max("Age"), "P.Age")
    .Add(Restrictions.EqProperty("LastName", "P.LastName"));

return session.CreateCriteria<Person>("P")
    .Add(Subqueries.Exists(subQuery))
    .List<Person>();

Upvotes: 1

Related Questions