2

I'm having a problem with my QueryOver and I don't understand why. My query returns the viewmodel object ContactInfo. I get this error on the Employee property: "could not find setter for property". How can I fill the Employee property within ContactInfo? What am I doing wrong?

ViewModel Object:

public class ContactInfo    
{
    public EmployeeInfo Employee { get; set; }
    public string Email { get; set; }
    public string InternalTelephone { get; set; }
}

Query

public override ContactInfo Execute()
    {
        ContactInfo r = null;
        EmployeeInfo ei = null;

        var result = Session.QueryOver<Job>()
            .JoinAlias(j => j.EmployeeInfo, () => ei)
            .Where(j => j.EmployeeInfo.Id == _employeeId)
            .Select(
                Projections.Property<Job>(j => ei.Id).WithAlias(() => r.Employee.Id),
                Projections.Property<Job>(j => ei.FirstName).WithAlias(() => r.Employee.FirstName),
                Projections.Property<Job>(j => ei.LastName).WithAlias(() => r.Employee.LastName),
                Projections.Property<Job>(j => ei.ReferenceCode).WithAlias(() => r.Employee.ReferenceCode),
                Projections.Property<Job>(j => j.Telefoon).WithAlias(() => r.InternalTelephone)
            )
            .TransformUsing(Transformers.AliasToBean<ContactInfo>())
            .Take(1)
            .SingleOrDefault<ContactInfo>();

        var email = Session.QueryOver<Employee>()
            .Where(e => e.Id == _employeeId)
            .Select(e => e.Email)
            .SingleOrDefault<string>();

        result.Email = email;

        return result;
    }
}
Nanou Ponette
  • 1,372
  • 4
  • 22
  • 46
  • 1
    I would say that solution is here: http://stackoverflow.com/a/26779306/1679310 or here http://stackoverflow.com/a/26901453/1679310 – Radim Köhler Jan 12 '15 at 10:52
  • @RadimKöhler I saw these solutions but your DeepTransformer class gives me a error at dictionary.Is() He does not recognize this function. Any fix for this? – Nanou Ponette Jan 12 '15 at 11:10

1 Answers1

1

What we can do is to use different than default result transformer, e.g. DeepTransformer.

In that case, the query must use Alias similar to the DTO model. So, if we have domain property ei.FirstName belonging to JoinAlias - j.EmployeeInfo - the alias must be reflecting the DTO ContactInfo - "EmployeeInfo.FirstName"

.Select(        
    Projections.Property<Job>(j => ei.FirstName)         // the mapped domain model
                          .As("EmployeeInfo.FirstName"), // the path in DTO/view model
    ...
)
.TransformUsing(DeepTransformern<ContactInfo>()) // the DTO

So now, the path "EmployeeInfo.FirstName" will be used to populate the Employee as a property EmployeeInfo and its property FirstName

And this Result transformer

DeepTransformer will use Alias to build up the reference tree. Could be used for references/many-to-one as well for IDictionary ... (but not for collections)

NOTE: The .Is() method comes from some extensions, and can be replaced with != null like

public static partial class Ext
{
    public static bool Is(this object value)
    {
        return value != null;
    }
....
Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335