2 Stimmen

Verwenden von SQL Server 2008-Geografie-Typen mit nHibernate's CreateSQLQuery

Ich versuche, ein SQL-Update-Statement mit nHibernate (2.0.1GA) wie folgt auszuführen:

sqlstring = string.Format("set nocount on;update myusers set geo=geography::Point({0}, {1}, 4326) where userid={2};", mlat, mlong, userid);
_session.CreateSQLQuery(sqlstring).ExecuteUpdate();

Allerdings erhalte ich den folgenden Fehler: 'geography@p0' ist kein anerkannter integrierter Funktionsname.

Ich dachte, CreateSQLQuery würde einfach das SQL, das ich ihm gegeben habe, übergeben und ausführen... anscheinend nicht. Irgendwelche Ideen, wie ich das im Kontext von nHibernate machen kann?

0 Stimmen

Wurde dieses Problem jemals im Quelltext behoben? Ich stoße auf das gleiche Problem.

4voto

Chris Shaffer Punkte 31499

Ich bin mir ziemlich sicher, dass ich dir sagen kann, was passiert, aber ich weiß nicht, ob es eine Lösung dafür gibt.

Ich glaube, das Problem ist, dass das ':' Zeichen von NHibernate verwendet wird, um einen benannten Parameter zu erstellen. Ihr Ausdruck wird geändert zu:

set nocount on;update myusers set geo=geography@p0({0}, {1}, 4326) where userid={2};

Und @p0 wird eine SQL-Variable sein. Leider konnte ich keine Dokumentation finden, um Anführungszeichen zu escapen, so dass sie nicht als benannter Parameter behandelt werden.

Wenn ein Escape-Zeichen existiert (mein schnelles Überfliegen des NHibernate-Quellcodes hat keines gefunden; Benannte Parameter werden in NHibernate.Engine.Query.ParameterParser behandelt, wenn du etwas mehr Zeit mit der Suche verbringen möchtest), dann könntest du das verwenden.

Weitere Lösungen:

  • Füge dem Quellcode ein Escape-Zeichen hinzu. Du kannst dann eine modifizierte Version von NHibernate verwenden. Wenn du das tust, solltest du deinen Patch dem Team vorlegen, damit er in das echte Produkt aufgenommen werden kann und du keine modifizierte Version des Quellcodes pflegen musst (kein Spaß).
  • Erstelle eine benutzerdefinierte Funktion in deiner Datenbank, die ein geography::Point zurückgibt, und rufe dann deine Funktion anstelle der Standard-SQL-Funktion auf. Das scheint der schnellste / einfachste Weg zu sein, um loszulegen, fühlt sich aber auch ein wenig wie eine Notlösung an.
  • Schaue nach, ob es in NHibernate Spatial etwas gibt, das es dir ermöglicht, das geography::Point() programmgesteuert hinzuzufügen [oder bearbeite den Code für dieses Projekt, um einen hinzuzufügen, und reiche den Patch bei diesem Team ein].

0voto

tonyz Punkte 191

"{was auch immer} ist kein anerkannter integrierter Funktionsname" ist eine SQL Server-Fehlermeldung. Ich bin mir nicht sicher, was Hibernate dort macht, aber SQL Server beschwert sich darüber.

0voto

mattk Punkte 1255

Es gibt eine implizite Konvertierung von varchar nach Punkt.

Verwenden Sie NHibernate, um die geografischen Parameter auf ihre Zeichenfolgendarstellung zu setzen

Definieren Sie eine SQL-Abfragenvorlage mit benanntem Parameter loc:

const string Query = @"SELECT   {location.*}
FROM     {location}
WHERE    {location}.STDistance(:loc) is not null
ORDER BY {location}.STDistance(:loc)";

Setzen Sie den Parameter auf eine Zeichenfolgendarstellung von Point:

return session
                .CreateSQLQuery(Query)
                .AddEntity("location", typeof (Location))
                .SetString("loc", "Point (53.39006999999999 -3.0084007)")
                .SetMaxResults(1)
                .UniqueResult();

Dies ist für ein Select. Aber ich sehe keinen Grund, warum es nicht für ein Insert oder Update funktionieren würde.

0voto

Yosoyadri Punkte 531

Im Anschluss an die Antwort von @Chris hier eine Kopier- und Einfügelösung:

CREATE FUNCTION GetPoint 
(
    @lat float,
    @lng float,
    @srid int
)
RETURNS geography
AS
BEGIN

declare @point geography = geography::Point(@lat, @lng, @srid);

RETURN @point

END
GO

Dann machst du

dbo.GetPoint(@Latitude, @Longitude, 4326)

anstatt

geography::Point(@Latitude, @Longitude, 4326);

Und NH ist glücklich

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X