NHibernate QueryOver和string.format

时间:2014-07-02 06:48:56

标签: c# nhibernate queryover

我在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;未定义

1 个答案:

答案 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;
    });