Benötigen Sie SQL Kriterien API Hilfe Umwandlung
-
08-07-2019 - |
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>
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?