nhibernatefluent-nhibernatenhibernate-criteria

Nhibernate Criteria retrieve child of parent with restriction on other child of parent


I need to be able to write the following query as a Criteria.

SELECT hist.*
FROM
    Administration admin
    INNER JOIN Item item ON item.AdministrationId = admin.AdministrationId
    INNER JOIN ItemHistory hist ON hist.ItemId = item.ItemId
WHERE
    item.itemId = @param
    and hist.IsError =
        (
            SELECT (CASE status.errorType
                        WHEN 'Warning' THEN 0
                        ELSE 1
                    END
                   )
            FROM
                AdminStatus status
            WHERE
                status.AdministrationId = admin.AdministrationId
                AND status.Group = 'Issues'
        )

I'm pretty sure I'll need to do the sub query as a detached criteria:

var status = DetachedCriteria.For<AdminStatus>("status");
        status.CreateAlias("status.Administration", "admin");
        status.Add(Restrictions.Eq("status.Group", "Issues"));
        status.SetProjection(Projections.Property("AdministrationId"));
        status.SetProjection(Projections.Conditional(
                        Restrictions.Eq("status.errorType", "Warning"),
                        Projections.Constant(0),
                        Projections.Constant(1)));

But I'm not sure how to join that with my primary criteria:

    var criteria = Session.CreateCriteria<ItemHIstory>("hist");
        criteria.CreateAlias("ItemHistory.Item", "item");
        criteria.CreateAlias("item.Administration", "admin");    

Solution

  • But I'm not sure how to join that with my primary criteria:

    Methods from Subqueries class glue detached sub-query with main criteria. Subqueries.PropertyEq in you case:

    var criteria = Session.CreateCriteria<ItemHIstory>("hist");
    criteria.CreateAlias("ItemHistory.Item", "item");
    criteria.CreateAlias("item.Administration", "admin");
    criteria.Add(Subqueries.PropertyEq("hist.IsError ", status))
    
    

    And regarding detached criteria. Alias creation seems unnecessary:

    var status = DetachedCriteria.For<AdminStatus>("status");
    
    status.Add(Restrictions.EqProperty("status.AdministrationId", "admin.AdministrationId"));
    status.Add(Restrictions.Eq("status.Group", "Issues"));
    
    status.SetProjection(Projections.Conditional(
                    Restrictions.Eq("status.errorType", "Warning"),
                    Projections.Constant(0),
                    Projections.Constant(1)));