Question

I'm fiddling with my repository class and attempted to execute a query with a detached criteria. However, it doesn't seem to like me setting the result transformer to a non AR-type.

public class IncidentRepository
{
    public static IList<AuditReport> GetAllIncidentsToAudit()
    {
        DetachedCriteria dc = DetachedCriteria.For<Incident>("i")
            .SetProjection(
                Projections.ProjectionList()
                    .Add(Projections.Property("i.Id"), "IncidentId")
                    .Add(Projections.Property("l.Id"), "LocationId")
            )
            .CreateCriteria("Locations", "l")
                .Add(Expression.Eq("l.PrimaryLocationFlag", "T"))
            .SetResultTransformer(Transformers.AliasToBean<AuditReport>());

        return ActiveRecordMediator<AuditReport>.FindAll(dc);
    }
}

public class AuditReport
{
    public int IncidentId { get; set; }
    public int LocationId { get; set; }
}

The error I get when executing this query is:

You have accessed an ActiveRecord class that wasn't properly initialized. There are two possible explanations: that the call to ActiveRecordStarter.Initialize() didn't include castle.AuditReport class, or that castle.AuditReport class is not decorated with the [ActiveRecord] attribute.

I understand the error but how can I return a strongly typed list of a non-AR type? I've looked at what NHibernate.Transform offers but nothing stands out.

Also, is doing this bad practice?

Edit: I managed to solve it by gaining access to the underlying database session and executing my criteria from there.

 ISession sess = ActiveRecordMediator.GetSessionFactoryHolder().
        CreateSession(typeof(ActiveRecordBase));
    ICriteria criteria = sess.CreateCriteria<Incident>("i")
        .SetProjection(
            Projections.ProjectionList()
                .Add(Projections.Property("i.Id"), "IncidentId")
                .Add(Projections.Property("l.Id"), "LocationId")
        )
        .CreateCriteria("Locations", "l")
            .Add(Expression.Eq("l.PrimaryLocationFlag", "T"))
        .SetResultTransformer(Transformers.AliasToBean<AuditReport>());

    return criteria.List<AuditReport>();

Now I'm wondering, is there another of achieving this without manually creating a new session?

Was it helpful?

Solution

If you want to use a class for a transformation-result, then you might need to "import" it to ActiveRecord.

Try decorating any AR class with (or maybe the AuditReport, but it might need to be a AR-decorated class):

[Import( typeof( AuditReport ), "AuditReport" )]

That would translate to the NHibernate import attribute in xml-config.

This atleast solve it when using a class construct in HQL, like this:

select new OrderSummary(o.Foo, count(o.Foo)) 
    from Orders o 
    group by o.Bar
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top