我正在尝试使用nHibernate(2.0.1GA)发出一个SQL更新语句,如下所示:
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的上下文中做到这一点的任何想法?
答案 0 :(得分:4)
我很确定我可以告诉你发生了什么,但我不知道是否有修复方法。
我认为问题是NHibernate使用':'字符来创建命名参数。您的表达式将更改为:
set nocount on;update myusers set geo=geography@p0({0}, {1}, 4326) where userid={2};
@ p0将成为一个SQL变量。遗憾的是,我找不到任何有关转义冒号的文档,因此它们不会被视为命名参数。
如果存在转义字符(我快速浏览NHibernate源代码没有找到;如果你想花一点时间搜索,可以在NHibernate.Engine.Query.ParameterParser中处理命名参数),那么你可以使用这一点。
其他解决方案:
答案 1 :(得分:0)
“{whatever}不是公认的内置函数名称”是一个SQL Server错误消息,不知道Hibernate在那里做了什么,但SQL Server是抱怨它的人。
答案 2 :(得分:0)
从varchar到Point的隐式转换。
使用NHibernate将地理参数设置为其字符串表示
使用命名参数loc
定义SQL查询模板:
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>();
这是一个选择。但是我没有理由认为它不能用于插入或更新。
答案 3 :(得分:0)
关于@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很高兴