How to select chosen columns from two different entities into one DTO using NHibernate?
Posted
by
Pawel Krakowiak
on Stack Overflow
See other posts from Stack Overflow
or by Pawel Krakowiak
Published on 2012-10-12T15:35:54Z
Indexed on
2012/10/12
15:36 UTC
Read the original article
Hit count: 213
I have two classes (just recreating the problem):
public class User
{
public virtual int Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual IList<OrgUnitMembership> OrgUnitMemberships { get; set; }
}
public class OrgUnitMembership
{
public virtual int UserId { get; set; }
public virtual int OrgUnitId { get; set; }
public virtual DateTime JoinDate { get; set; }
public virtual DateTime LeaveDate { get; set; }
}
There's a Fluent NHibernate map for both, of course:
public class UserMapping : ClassMap<User>
{
public UserMapping()
{
Table("Users");
Id(e => e.Id).GeneratedBy.Identity();
Map(e => e.FirstName);
Map(e => e.LastName);
HasMany(x => x.OrgUnitMemberships)
.KeyColumn(TypeReflector<OrgUnitMembership>
.GetPropertyName(p => p.UserId))).ReadOnly().Inverse();
}
}
public class OrgUnitMembershipMapping : ClassMap<OrgUnitMembership>
{
public OrgUnitMembershipMapping()
{
Table("OrgUnitMembership");
CompositeId()
.KeyProperty(x=>x.UserId)
.KeyProperty(x=>x.OrgUnitId);
Map(x => x.JoinDate);
Map(x => x.LeaveDate);
References(oum => oum.OrgUnit)
.Column(TypeReflector<OrgUnitMembership>
.GetPropertyName(oum => oum.OrgUnitId)).ReadOnly();
References(oum => oum.User)
.Column(TypeReflector<OrgUnitMembership>
.GetPropertyName(oum => oum.UserId)).ReadOnly();
}
}
What I want to do is to retrieve some users based on criteria, but I would like to combine all columns from the Users table with some columns from the OrgUnitMemberships table, analogous to a SQL query:
select u.*, m.JoinDate, m.LeaveDate
from Users u inner join OrgUnitMemberships m on u.Id = m.UserId
where m.OrgUnitId = :ouid
I am totally lost, I tried many different options. Using a plain SQL query almost works, but because there are some nullable enums in the User class AliasToBean fails to transform, otherwise wrapping a SQL query would work like this:
return
Session
.CreateSQLQuery(sql)
.SetParameter("ouid", orgUnitId)
.SetResultTransformer(Transformers.AliasToBean<UserDTO>())
.List<UserDTO>()
I tried the code below as a test (a few different variants), but I'm not sure what I'm doing. It works partially, I get instances of UserDTO back, the properties coming from OrgUnitMembership (dates) are filled, but all properties from User are null:
User user = null;
OrgUnitMembership membership = null;
UserDTO dto = null;
var users = Session.QueryOver(() => user)
.SelectList(list => list
.Select(() => user.Id)
.Select(() => user.FirstName)
.Select(() => user.LastName))
.JoinAlias(u => u.OrgUnitMemberships, () => membership)
//.JoinQueryOver<OrgUnitMembership>(u => u.OrgUnitMemberships)
.SelectList(list => list
.Select(() => membership.JoinDate).WithAlias(() => dto.JoinDate)
.Select(() => membership.LeaveDate).WithAlias(() => dto.LeaveDate))
.TransformUsing(Transformers.AliasToBean<UserDTO>())
.List<UserDTO>();
© Stack Overflow or respective owner