Frage

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)
War es hilfreich?

Lösung

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)

Andere Tipps

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>());
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top