【问题标题】:Need help converting SQL to criteria API需要帮助将 SQL 转换为标准 API
【发布时间】:2009-11-29 15:20:08
【问题描述】:

我有一个当前使用 SQL Server 用户定义函数的 NHibernate 应用程序。我想避免调用这个函数,而是使用 NH 标准 API 来表达它的逻辑。不幸的是,我很难将 NH 文档中的标准示例应用于我的特定案例。所以我转向这个网站寻求帮助。

这里是函数。它接受一个字符串参数并返回一个表。该函数在相同的 2 个表之间执行 3 次连接,但连接条件不同,然后合并结果。

任何提示将不胜感激。提前致谢!

编辑:这是针对 NH 2.1

编辑:已接受答案中的注释指出无法进行转换,这是正确答案。

CREATE FUNCTION dbo.GetRevisionText
(
  @LangId NVARCHAR(16)
)
RETURNS TABLE
AS
RETURN
(
  SELECT r.RevisionId,
    COALESCE(lp1.Title, lp2.Title, lp3.Title) Title,
    COALESCE(lp1.Description, lp2.Description, lp3.Description) Description
    FROM Revision r
      LEFT JOIN LocalizedProperty lp1
        ON lp1.RevisionId = r.RevisionId
        AND lp1.LanguageId = @LangId
      LEFT JOIN LocalizedProperty lp2
        ON lp2.RevisionId = r.RevisionId
        AND lp2.LanguageId = LEFT(@LangId, 2)
      LEFT JOIN LocalizedProperty lp3
        ON lp3.RevisionId = r.RevisionId
        AND lp3.LanguageId = r.DefaultPropertiesLanguage
);

这是涉及的 3 个类的映射:

<class name="Revision">
  <id name="RevisionId" type="Guid">
    <generator class="assigned"/>
  </id>
  <set name="LocalizedProperties" inverse="true" lazy="true" cascade="all-delete-orphan">
    <key column="RevisionId"/>
    <one-to-many class="LocalizedProperty"/>
  </set>
  <many-to-one name="DefaultPropertiesLanguage" class="Language" not-null="true"/>
</class>

<class name="Language">
  <id name="LanguageId" type="String" length="16">
    <generator class="assigned"/>
  </id>
  <property name="Lcid" type="Int32" unique="true" not-null="true"/>
</class>

<class name="LocalizedProperty" mutable="false">
  <composite-id>
    <key-many-to-one name="Revision" class="Revision" column="RevisionId"/>
    <key-many-to-one name="Language" class="Language" column="LanguageId"/>
  </composite-id>
  <property name="Title" type="String" length="200" not-null="true"/>
  <property name="Description" type="String" length="1500" not-null="false"/>
</class>

【问题讨论】:

    标签: nhibernate icriteria


    【解决方案1】:

    这可能会起作用(NH 1.2):

    var crit = nhSes.CreateCriteria(typeof(Revision), "r")
     .SetProjection(
      Projections.SqlProjection(@"r.RevisionId as rid,
        COALESCE(lp1.Title, lp2.Title, lp3.Title) as Title,
        COALESCE(lp1.Description, lp2.Description, lp3.Description) as Description", new[] {"rid", "Title", "Description"}, new[] {NHibernateUtil.Guid, NHibernateUtil.String,NHibernateUtil.String})
     );
    
    crit.CreateCriteria("LocalizedProperty", "lp1", JoinType.InnerJoin);
    crit.CreateCriteria("LocalizedProperty", "lp2", JoinType.InnerJoin);
    crit.CreateCriteria("LocalizedProperty", "lp3", JoinType.InnerJoin);
    
    crit.Add(Expression.Eq("lp1.LanguageId", langId));
    crit.Add(Expression.Sql("lp2.LanguageId = LEFT(:LangId, 2)", langId, NHibernateUtil.String));
    crit.Add(Expression.EqProperty("lp3.LanguageId", "r.DefaultPropertiesLanguage"));
    

    但是请注意,这不会生成 ANSI 语法连接,而是将约束放在 WHERE 子句中。我真的不认为这是一个问题,您正在执行内部连接而不是外部连接。

    另外我现在不记得Expression.Sql 上的正确参数符号了。 我将其定义为:LangId,尽管它也可能是@LangId

    旁注:如您所见,虽然这是一个条件查询,但它只是将一堆 sql 语句拆分为符合条件 API;你确定这是你需要的吗?

    【讨论】:

    • 感谢您的帮助,它给了我帮助。不幸的是,它不起作用:( NH 抱怨“重复关联路径:LocalizedProperty”。我目前正在研究将第二个和第三个 LocalizedProperty 别名与视图映射......
    • 你试过用 crit.CreateAlias("LocalizedProperty", "lp1");它可能会抛出同样的错误,但你没有什么可松动的
    • 嗯,它似乎不受支持...检查nhjira.koah.net/browse/NH-2016...如果您真的想将代码从数据库移植到您的应用程序,ISQLQuery 是唯一的方法
    猜你喜欢
    • 2020-05-11
    • 1970-01-01
    • 2018-11-24
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多