I have an nhibernate issue where I am projecting the sql Coalesce function.

I am comparing two string properties having the same name, from two different entities. In the resulting sql, the same property from only the first entity is being compared thus:

var list = Projections.ProjectionList();
list.Add(
   Projections.SqlFunction("Coalesce",
    NHibernateUtil.String,
    Projections.Property<TranslatedText>(tt => tt.ItemText),
    Projections.Property<TextItem>(ti => ti.ItemText)));

var q = Session.QueryOver<TextItem>()
    .Left.JoinQueryOver(ti => ti.TranslatedItems);

Evaluating q results in this sql

coalesce(this_.ItemText, this_.ItemText)

the this_ in the RHS needs to be an aliased table

I can use Projections.Alias(Projections.Property<TranslatedText>(tt => tt.ItemText), "ttAlias") but am not sure how to map "ttAlias" in the JoinQueryOver.

I can create an alias there too, but can't see how to name it.

TranslatedText ttAlias = null;
...
JoinQueryOver(ti => ti.TranslatedItems, () => ttAlias)
有帮助吗?

解决方案

Aliases are variables in QueryOver, like you showed in the JoinQueryOver call. Alias names (strings) should not be needed in QueryOver, they are for Criteria queries.

To the problem itself: I can't test it right now, but I think this should work:

Projections.Property(() => ttAlias.ItemText)

其他提示

I used this topic as a resource while writing a unit test. This QueryOver works well and may help others with similar issues. QueryOver still struggles with property mapping to transformers using expressions. It's technically possible to remove "Id" but IMHO it hinders clarity.

The complete example is on GitHub

         String LocalizedName = "LocalizedName";
         //Build a set of columns with a coalese
         ProjectionList plColumns = Projections.ProjectionList();
         plColumns.Add(Projections.Property<Entity>(x => x.Id), "Id");
         plColumns.Add(Projections.SqlFunction("coalesce",
                                               NHibernateUtil.String,
                                               Projections.Property<Entity>(x => x.EnglishName),
                                               Projections.Property<Entity>(x => x.GermanName))
                                  .WithAlias(() => LocalizedName));

         ProjectionList plDistinct = Projections.ProjectionList();
         plDistinct.Add(Projections.Distinct(plColumns));


         //Make sure we parse and run without error
         Assert.DoesNotThrow(() => session.QueryOver<Entity>()
                                          .Select(plDistinct)
                                          .TransformUsing(Transformers.AliasToBean<LocalizedEntity>())
                                          .OrderByAlias(() => LocalizedName).Asc
                                          .Skip(10)
                                          .Take(20)
                                          .List<LocalizedEntity>());
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top