Нужна помощь в преобразовании SQL в API критериев

У меня есть приложение NHibernate, которое в настоящее время использует пользовательскую функцию SQL Server. Я хотел бы избежать вызова этой функции и вместо этого выразить ее логику с помощью API критериев NH. К сожалению, у меня возникли трудности с применением примеров критериев в документации NH к моему конкретному случаю. Поэтому обращаюсь к этому сайту за помощью.

Вот функция. Он принимает один строковый аргумент и возвращает таблицу. Функция выполняет 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
);

Вот сопоставление для трех задействованных классов:

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

person Paul Lalonde    schedule 29.11.2009    source источник


Ответы (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 критериев; вы уверены, что это то, что вам нужно?

person Jaguar    schedule 30.11.2009
comment
Спасибо за вашу помощь, это дало мне ногу. К сожалению, это не работает :( NH жалуется на повторяющийся путь ассоциации: LocalizedProperty. В настоящее время я изучаю сопоставление 2-го и 3-го псевдонимов LocalizedProperty с представлениями... - person Paul Lalonde; 01.12.2009
comment
вы пытались использовать crit.CreateAlias(LocalizedProperty, lp1); он, вероятно, выдаст ту же ошибку, но вам нечего терять - person Jaguar; 01.12.2009
comment
мне кажется, что это не поддерживается... проверьте nhjira.koah.net/browse/NH- 2016... если вы действительно хотите перенести код из БД в свое приложение, ISQLQuery — единственный способ - person Jaguar; 01.12.2009