我在NHibernate中使用QueryOver,我想使用以下语法自定义我投影DTO的一个属性:
IEnumerable<PersonResponseMessage> persons =
session.QueryOver<PersonEntity>()
.SelectList(list => list
.Select(p => p.Active).WithAlias(() => dto.Active)
.Select(p => p.Alert).WithAlias(() => dto.Alert)
.Select(p => p.Comments).WithAlias(() => dto.Comments)
.Select(p => string.Format("{0}api/Person/{1}", uriHelper.Root, p.Id)).WithAlias(() => dto.DetailsUrl)
)
.TransformUsing(Transformers.AliasToBean<PersonResponseMessage>())
.List<PersonResponseMessage>();
不幸的是,NHibernate无法做到这一点,并抛出一个例外说:
从范围引用的变量P&#34;&#34;未定义
答案 0 :(得分:4)
共同有两种方式。部分我们可以在DB端移动该concat操作,如下所述:
在这种情况下,我们会使用Projections.Concat
:
.SelectList(list => list
.Select(p => p.Active).WithAlias(() => dto.Active)
.Select(p => p.Alert).WithAlias(() => dto.Alert)
.Select(p => p.Comments).WithAlias(() => dto.Comments)
// instead of this
//.Select(p => string.Format("{0}api/Person/{1}", uriHelper.Root, p.Id))
// .WithAlias(() => dto.DetailsUrl)
// use this
.Select(p => Projections.Concat(uriHelper.Root, Projections.Concat, p.Id))
.WithAlias(() => dto.DetailsUrl)
)
.TransformUsing(Transformers.AliasToBean<PersonResponseMessage>())
.List<PersonResponseMessage>();
但我会在C#中投票支持应用层的事后处理:
.SelectList(list => list
.Select(p => p.Active).WithAlias(() => dto.Active)
.Select(p => p.Alert).WithAlias(() => dto.Alert)
.Select(p => p.Comments).WithAlias(() => dto.Comments)
// just the ID
.Select(p => p.Id).WithAlias(() => dto.Id)
)
.TransformUsing(Transformers.AliasToBean<PersonResponseMessage>())
.List<PersonResponseMessage>()
// do the concat here, once the data are transformed and in memory
.Select(result =>
{
result.DetailsUrl = string.Format("{0}api/Person/{1}", uriHelper.Root, p.Id)
return result;
});