Search code examples
c#nhibernateprojection

Nhibernate project into class property


How can I project into class property using NHibernate? For example:

[Test]
public void Test()
{
    MyClass dto = null;

    var test = CurrentSession.CreateCriteria<Contact>()
        .Add(Restrictions.Eq("ContactName", "John Smith"))
        .SetProjection(Projections.ProjectionList()
            .Add(Projections.Property("ContactName").WithAlias(() => dto.SubClass.Name))
            .Add(Projections.Property("EmailAddress").WithAlias(() => dto.Email))
        )
        .SetResultTransformer(Transformers.AliasToBean<MyClass>())
        .List<MyClass>();

    Assert.That(test[0].SubClass.Name, Is.EqualTo("John Smith"));
}

class MyClass
{
    public string Email { get; set; }

    public MySubClass SubClass { get; set; }
}

class MySubClass
{
    public string Name { get; set; }
}

As you see I have a simple query and want to transform 1 row into 1 object - without lists but with a subclass. Unfortunately, it fails:

NHibernate.PropertyNotFoundException : Could not find a setter for property 'Name' in class 'MyTest+MyClass'

Is it possible to achieve this behaviour without custom transformer?


Solution

  • The default result transformer will be able to fill the root entity properties. But we can introduce our custom result transformer. There is one I do use:

    Which is ready to convert . notation into chain of inner objects (excluding collections)

    So, if you'll take it, and reuse it, this syntax would work:

    ...
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.Property("ContactName").As("SubClass.Name"))
        .Add(Projections.Property("EmailAddress").As("Email"))
    )
    .SetResultTransformer(DeepTransformer<MyClass>())
    

    You can even improve it, but the idea of custom transformer should be clear now