Использование типов географии SQL Server 2008 с CreateSQLQuery nHibernate - PullRequest
2 голосов
/ 26 октября 2008

Я пытаюсь выполнить оператор обновления SQL с помощью nHibernate (2.0.1GA) следующим образом:

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

Однако я получаю следующую ошибку: 'geography @ p0' не является распознанным именем встроенной функции.

Я думал, что CreateSQLQuery просто передаст SQL, который я дал, и выполнит его ... не думаю. Любые идеи о том, как я могу сделать это в контексте nHibernate?

Ответы [ 4 ]

4 голосов
/ 16 марта 2009

Я почти уверен, что могу рассказать вам, что происходит, но я не знаю, есть ли решение для этого.

Я думаю, проблема в том, что символ ':' используется NHibernate для создания именованного параметра. Ваше выражение меняется на:

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

И @ p0 будет переменной SQL. К сожалению, я не могу найти никакой документации по экранированию двоеточий, поэтому они не рассматриваются как именованные параметры.

Если существует escape-символ (мой быстрый просмотр источника NHibernate не нашел его; Именованные параметры обрабатываются в NHibernate.Engine.Query.ParameterParser, если вы хотите потратить немного больше времени на поиск), тогда вы можете использовать что.

Другие решения:

  • Добавить escape-символ к источнику. Затем вы можете использовать модифицированную версию NHibernate. Если вы сделаете это, вы должны представить свой патч команде, чтобы он мог быть включен в реальную вещь, и вам не нужно поддерживать измененную версию исходного кода (без удовольствия).
  • Создайте пользовательскую функцию в вашей БД, которая возвращает geography :: Point, а затем вызовите вашу функцию вместо стандартной функции SQL. Это кажется самым быстрым / простым способом начать работу, но при этом ощущается как пластырь.
  • Посмотрите, есть ли в NHibernate Spatial что-то, что позволит вам программно добавить geography :: Point () [или отредактировать код для этого проекта, чтобы добавить его и отправить патч этой команде].
0 голосов
/ 26 апреля 2015

После ответа @ Chris, вот решение для копирования и вставки:

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

Вы делаете

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

вместо

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

И NH счастлив

0 голосов
/ 06 марта 2013

Существует неявное преобразование из varchar в Point.

Используйте NHibernate, чтобы установить для географических параметров их строковое представление

Определить шаблон запроса SQL с именованным параметром loc:

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

Установить параметр в строковое представление Point:

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

Это для выбора. но я не вижу причин, по которым он не будет работать для вставки или обновления.

0 голосов
/ 14 марта 2009

«{что-то} не является распознанным именем встроенной функции» - это сообщение об ошибке SQL Server, не уверенное, что там делает Hibernate, но именно SQL Server жалуется на это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...