代码之家  ›  专栏  ›  技术社区  ›  Paul Lalonde

需要帮助将SQL转换为条件API

  •  0
  • Paul Lalonde  · 技术社区  · 15 年前

    我有一个nhibernate应用程序,当前使用的是SQL Server用户定义函数。我想避免调用这个函数,而是使用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>
    
    1 回复  |  直到 15 年前
        1
  •  1
  •   Jaguar    15 年前

    这可能起到作用(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;您确定这是您需要的吗?

    推荐文章