如何使用NHibernate从两个不同的实体中选择所选列到一个DTO中?

时间:2012-10-12 15:35:54

标签: nhibernate join fluent-nhibernate

我有两个类(只是重新创建问题):

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; }
}

当然,两者都有流利的NHibernate地图:

    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();
        }
    }

我想要做的是根据条件检索一些用户,但我想将Users表中的所有列与OrgUnitMemberships表中的一些列组合在一起,类似于SQL查询:

select u.*, m.JoinDate, m.LeaveDate
from Users u inner join OrgUnitMemberships m on u.Id = m.UserId
where m.OrgUnitId = :ouid

我完全迷失了,我尝试了很多不同的选择。使用普通的SQL查询几乎可以工作,但是因为在用户类中有一些可以为空的枚举,所以AliasToBean无法转换,否则包装SQL查询将如下工作:

return
    Session
        .CreateSQLQuery(sql)
        .SetParameter("ouid", orgUnitId)
        .SetResultTransformer(Transformers.AliasToBean<UserDTO>())
        .List<UserDTO>()

我尝试下面的代码作为测试(一些不同的变体),但我不确定我在做什么。它部分工作,我得到UserDTO的实例,来自OrgUnitMembership(日期)的属性被填充,但User的所有属性都为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>();

1 个答案:

答案 0 :(得分:1)

如此接近..只需加入你的2个SelectList方法 - 你的别名将确保NHibernate从正确的实体获得正确的属性:

User user = null;
OrgUnitMembership membership = null;
UserDTO dto = null;
var users = Session.QueryOver(() => user)
    .JoinAlias(u => u.OrgUnitMemberships, () => membership)
    //.JoinQueryOver<OrgUnitMembership>(u => u.OrgUnitMemberships)
    .SelectList(list => list
        .Select(() => user.Id)
        .Select(() => user.FirstName)
        .Select(() => user.LastName))
        .Select(() => membership.JoinDate).WithAlias(() => dto.JoinDate)
        .Select(() => membership.LeaveDate).WithAlias(() => dto.LeaveDate))
    .TransformUsing(Transformers.AliasToBean<UserDTO>())
    .List<UserDTO>();