문제

현재 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>
도움이 되었습니까?

해결책

이것은 작업을 수행 할 수 있습니다 (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

Sidenote : 당신이 알 수 있듯이 이것은 기준 쿼리이지만 기준 API에 맞게 SQL- 스테이트가 나뉘어져 있습니다. 이것이 당신이 필요한 것임을 확신합니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top