NHibernate QueryOver,Projections和Aliases

时间:2011-10-19 12:35:42

标签: nhibernate queryover nhibernate-projections

我有一个nhibernate问题,我正在投影sql Coalesce函数。

我正在比较来自两个不同实体的两个具有相同名称的字符串属性。在生成的sql中,仅比较来自第一个实体的相同属性:

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);

在此sql中评估q结果

coalesce(this_.ItemText, this_.ItemText)

RHS中的this_需要是别名表

我可以使用Projections.Alias(Projections.Property<TranslatedText>(tt => tt.ItemText), "ttAlias")但不确定如何在JoinQueryOver中映射“ttAlias”。

我也可以在那里创建别名,但无法看到如何命名。

TranslatedText ttAlias = null;
...
JoinQueryOver(ti => ti.TranslatedItems, () => ttAlias)

2 个答案:

答案 0 :(得分:6)

别名是QueryOver中的变量,就像您在JoinQueryOver调用中所显示的那样。在QueryOver中不应该需要别名(字符串),它们用于Criteria查询。

问题本身:我现在无法测试,但我认为这应该有效:

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

答案 1 :(得分:0)

我在编写单元测试时将此主题用作资源。此QueryOver运行良好,可以帮助其他类似问题。 QueryOver仍然在使用表达式与变换器的属性映射进行斗争。技术上可以删除“Id”,但恕我直言,它会妨碍清晰度。

完整示例位于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>());