Frage

Ich habe eine NHibernate-Anwendung, die zur Zeit die Verwendung einer SQL Server benutzerdefinierte Funktion macht. Ich möchte, um zu vermeiden, diese Funktion aufzurufen, und statt dessen Logik drücken die NH Kriterien API. Leider hat ich habe Schwierigkeiten, die Kriterien Beispiele in der NH-Dokumentation zu meinem speziellen Fall anwenden. Also ich um Hilfe zu dieser Seite drehen.

Hier ist die Funktion. Es dauert ein einzelnes String-Argument und gibt eine Tabelle. Die Funktion führt drei Verbindungen zwischen den gleichen zwei Tabellen, jedoch mit unterschiedlichen Kriterien verbinden, und verschmilzt dann das Ergebnis.

Für Hinweise wäre sehr hilfreich. Vielen Dank im Voraus!

Edit: Dies zielt NH 2.1

Edit: Ein Kommentar in der akzeptierten Antwort heißt es, dass die Umwandlung nicht möglich ist, die die richtig Antwort

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

Hier ist die Zuordnung für die drei beteiligten Klassen:

<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>
War es hilfreich?

Lösung

Dies könnte den Job (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"));

ist jedoch zu beachten, dass dies nicht ANSI-Syntax generiert verbinden, stellt aber die Zwänge in einer WHERE-Klausel. Ich glaube nicht wirklich, das ist ein Problem, Sie tun eine innere Verknüpfung und nicht eine äußere Verknüpfung.

Auch ich erinnere mich jetzt nicht die richtigen Parameter Notation auf Expression.Sql. Ich habe es als :LangId definiert obwohl es auch @LangId werden kann,

Nebenbei bemerkt: wie Sie sehen können, obwohl dies ein Kriterium aufgespalten Abfrage seine nur eine Reihe von SQL-Anweisungen so die Kriterien API passen; sind Sie sicher, dass das ist, was Sie brauchen?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top