【发布时间】:2015-04-30 08:39:57
【问题描述】:
我想用他们的Characters 集合检索简短的User 版本列表(也是简短版本)。我将 QueryOver 与投影一起使用。
public class User
{
public virtual int Id { get; set; }
public virtual string Nickname { get; set; }
public virtual ISet<Character> Characters { get; set; }
// and 30 other properties
}
public class Character
{
public virtual int Id { get; set; }
public virtual int XP { get; set; }
public virtual int UserId { get; set; }
public virtual int ClassId { get; set; }
// and 30 other properties
}
public class UserDto // short version
{
public virtual string Nickname { get; set; }
public virtual ISet<CharacterDto> Characters { get; set; }
}
public class CharacterDto // short version
{
public virtual int XP { get; set; }
public virtual int ClassId { get; set; }
}
User userAlias = null;
UserDto userDto = null;
Character characterAlias = null;
CharacterDto characterDto = null;
var result = session.QueryOver<User>(() => userAlias)
.Where(Restrictions.Like(
Projections.SqlFunction("lower", NHibernateUtil.String, Projections.Property<User>(x => x.Nickname)),
nickname.ToLowerInvariant(), MatchMode.Start))
.JoinAlias(x => x.Characters, () => characterAlias, JoinType.LeftOuterJoin)
.Select(
Projections.Property(() => userAlias.Nickname).WithAlias(() => userDto.Nickname),
Projections.Property(() => userAlias.Characters).WithAlias(() => userDto.Characters),
Projections.Property(() => characterAlias.XP).WithAlias(() => characterDto.XP),
Projections.Property(() => characterAlias.ClassId).WithAlias(() => characterDto.ClassId)
)
.TransformUsing(Transformers.AliasToBean<UserDto>())
.Take(50)
.List<UserDto>();
当我运行此代码时,它会引发异常:Could not find a setter for property ClassId in class UserDto。如果我删除转换器,则结果包含每个用户一个字符的条目(User1-Character1,User1-Character2,...)。每个条目都有正确的昵称和字符类 id,但错误的 xp(而不是用户 id)和字符集合(== null)。
如何在不使用 hql 或单独查询字符的情况下获取正确的数据?
更新
我删除了转换器并注释掉了Projections.Property(() => userAlias.Characters)...,现在它返回了正确的结果,但是有没有办法像 AliasToBeanTransformer 那样将它们转换为投影的 dto 并折叠每个字符条目的重复用户数据?
【问题讨论】:
-
您正在尝试投影到两种不同的对象类型(
UserDto和CharacterDto)。我不认为它被支持。如果你查看你的代码,你告诉 NHibernate 他应该使用UseDto(Transformers.AliasToBean<UserDto>()),但你没有告诉它CharacterDto。 -
好的,那么正确的方法是什么?另请参阅有关它不返回正确的
xp值但使用user_ids 代替的部分。 -
通常这个
Projections.SqlFunction("lower",应该没用,因为SQL Server中的列默认是不区分大小写的。 -
@xanatos 我使用 postgresql
标签: c# nhibernate outer-join queryover nhibernate-projections