Search code examples
nhibernateprojectionqueryover

Use of Cast Projection inside a Concat Projection


I have the following query:

var result = _session.QueryOver<Entity>()
    .Where(e => e.Property == value)
    .SelectList(list => list
        .Select(f => Projections.Concat("prefix-", e.BigIntProperty)).WithAlias(() => alias.Whatever)
        ...
    )
    .TransformUsing(Transformers.AliasToBean<Model>())
    .Future<Model>();

The problem is that Projections.Concat() accepts only strings and since e.BigIntProperty is not, the above doesn't compile. Is there a way to cast e.BigIntProperty to string?

I tried something like the following, which doesn't work either:

.Select(f => Projections.Concat("prefix-", Projection.Cast(NHibernateUtil.String, e.BigIntProperty))).WithAlias(() => alias.Whatever)

, since Projections.Cast returns an IProjection and not a string.


Solution

  • Projections.Cast seems terribly limited in that it can't take arbitrary Projections. Luckily you can easily create your own custom projection that enables you to do that:

    public static class CustomProjections
    {
        public static IProjection Concat(params IProjection[] projections)
        {
            return Projections.SqlFunction(
                "concat",
                NHibernateUtil.String,
                projections);
        }
    }
    

    Then, you'll be able to use your CustomProjections class like this:

    var result = _session.QueryOver<Entity>()
        .Where(e => e.Property == value)
        .SelectList(list => list
            .Select(CustomProjections.Concat(
                Projections.Constant("prefix-"),
                Projections.Cast(
                    NHibernateUtil.String,
                    Projections.Property<Entity>(e => e.BigIntProperty))))
                .WithAlias(() => alias.Whatever)
            ...
        )
        .TransformUsing(Transformers.AliasToBean<Model>())
        .Future<Model>();