NHibernate将地理类型传递给命名查询SetParameter()

NHibernate将地理类型传递给命名查询SetParameter(),nhibernate,named-query,sqlgeography,Nhibernate,Named Query,Sqlgeography,我正在将NHibernate 3引入ASP.NET MVC web应用程序的数据访问层 在SQL Server 2008 R2数据库中,地理数据类型用于在映射到应用程序中实体的表中存储纬度/经度坐标(称为EntityA) 我已经设置了fluent映射,成功地将数据类型映射到类型为GisharpBlog.NetTopologySuite.Geometrics.Point的EntityA上的属性,并使用自定义映射约定将其映射到派生的MsSql2008GeographyType 以上各项似乎都正常工作

我正在将NHibernate 3引入ASP.NET MVC web应用程序的数据访问层

在SQL Server 2008 R2数据库中,地理数据类型用于在映射到应用程序中实体的表中存储纬度/经度坐标(称为
EntityA

我已经设置了fluent映射,成功地将数据类型映射到类型为
GisharpBlog.NetTopologySuite.Geometrics.Point
EntityA
上的属性,并使用自定义映射约定将其映射到派生的
MsSql2008GeographyType

以上各项似乎都正常工作,但仍有一些存储过程在使用,它们期望一个参数的类型为
geography
。我已经将存储过程映射为命名查询,但似乎无法确定应该为
geography
类型的参数传递什么类型。发生查询调用的方法采用
double
纬度和
double
经度。在旧的存储过程调用中,映射是用

private static SqlGeography GetPoint(double latitude, double longitude)
{
    var geographyBuilder = new SqlGeographyBuilder();
    geographyBuilder.SetSrid(4326);
    geographyBuilder.BeginGeography(OpenGisGeographyType.Point);
    geographyBuilder.BeginFigure(latitude, longitude);
    geographyBuilder.EndFigure();
    geographyBuilder.EndGeography();
    return geographyBuilder.ConstructedGeography;
}

var point = GetPoint(latitude, longitude);

command.Parameters.Add(
    new SqlParameter("@Location", point) { UdtTypeName = "Geography" });
运行SQL探查器时,将执行以下命令

declare @p3 sys.geography
set @p3=convert(sys.geography,0xE6100000010CAD4D637B2DBA49400BEE77280AB404C0)
exec my-sproc-name @Location=@p3
exec sp_executesql N'exec my-sproc-name @p0' @p0=0x0001000000FFFFFFFF01000000000000000C02000000574E6574546F706F6C6F677953756974652C2056657273696F6E3D312E372E332E31373239382C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D663538306130353031366562616461310C030000004947656F4150492C2056657273696F6E3D312E312E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D6131613064613764656634363536373805010000002E4769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E506F696E74090000000B636F6F7264696E6174657308656E76656C6F70651047656F6D657472792B666163746F72791147656F6D657472792B75736572446174611147656F6D657472792B656E76656C6F70650D47656F6D657472792B737269641247656F6D657472792B64696D656E73696F6E1147656F6D657472792B626F756E646172791A47656F6D657472792B626F756E6461727944696D656E73696F6E040404020400040404404769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E436F6F7264696E617465417272617953657175656E6365020000001B47656F4150492E47656F6D6574726965732E49456E76656C6F706503000000384769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E47656F6D65747279466163746F7279020000001B47656F4150492E47656F6D6574726965732E49456E76656C6F706503000000081C47656F4150492E47656F6D6574726965732E44696D656E73696F6E73030000001B47656F4150492E47656F6D6574726965732E4947656F6D65747279030000001C47656F4150492E47656F6D6574726965732E44696D656E73696F6E73030000000200000009040000000A09050000000A0A0000000005FAFFFFFF1C47656F4150492E47656F6D6574726965732E44696D656E73696F6E73010000000776616C75655F5F000803000000000000000A01F9FFFFFFFAFFFFFF000000000504000000404769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E436F6F7264696E617465417272617953657175656E6365010000000B636F6F7264696E61746573041F47656F4150492E47656F6D6574726965732E49436F6F7264696E6174655B5D030000000200000009080000000505000000384769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E47656F6D65747279466163746F7279030000000E707265636973696F6E4D6F64656C19636F6F7264696E61746553657175656E6365466163746F72790473726964040400374769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E507265636973696F6E4D6F64656C02000000474769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E436F6F7264696E617465417272617953657175656E6365466163746F72790200000008020000000909000000090A000000000000000708000000000100000001000000041D47656F4150492E47656F6D6574726965732E49436F6F7264696E61746503000000090B0000000509000000374769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E507265636973696F6E4D6F64656C02000000096D6F64656C54797065057363616C6504002147656F4150492E47656F6D6574726965732E507265636973696F6E4D6F64656C7303000000060200000005F4FFFFFF2147656F4150492E47656F6D6574726965732E507265636973696F6E4D6F64656C73010000000776616C75655F5F000803000000000000000000000000000000050A000000474769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E436F6F7264696E617465417272617953657175656E6365466163746F72790000000002000000050B000000334769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E436F6F7264696E6174650300000001780179017A000000060606020000000BEE77280AB404C0AD4D637B2DBA4940000000000000F8FF0B
当我尝试使用以下映射时

var query = Session.GetNamedQuery("my-sproc-name");

var point = 
    new GisSharpBlog.NetTopologySuite.Geometries.Point(longitude, latitude);
query.SetParameter("Location", point);
我得到一个SqlException,将数据类型varbinary转换为地理位置时出错

[SqlException(0x80131904):将数据类型varbinary转换为 地理位置。将数据类型varbinary转换为地理位置时出错。]
System.Data.SqlClient.SqlConnection.OnError(SqlException异常, 布尔断开连接)+2073502
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔断开连接)+5064460
System.Data.SqlClient.TdsParser.throweexception和warning()+234
System.Data.SqlClient.TdsParser.Run(RunBehavior, SqlCommand cmdHandler、SqlDataReader数据流、, BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj)+2275
System.Data.SqlClient.SqlDataReader.ConsumerMetadata()+33
System.Data.SqlClient.SqlDataReader.get_MetaData()+86
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, 运行行为运行行为,字符串重置选项字符串)+311
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior、Boolean returnStream、Boolean 异步)+987
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、布尔返回流、字符串 方法,DbAsyncResult结果)+162
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、布尔返回流、字符串 方法)+32
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法)+141
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior 行为)+12
System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader() +12 NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)+356 NHibernate.Driver.BatcherDataReaderRapper..ctor(IBatcher batcher,IDbCommand command)+183
NHibernate.Driver.BasicResultSetCommand.GetReader(可为null的`1 commandTimeout)+432 NHibernate.Impl.MultiQueryImpl.DoList()+683

运行SQL探查器时,将执行以下命令

declare @p3 sys.geography
set @p3=convert(sys.geography,0xE6100000010CAD4D637B2DBA49400BEE77280AB404C0)
exec my-sproc-name @Location=@p3
exec sp_executesql N'exec my-sproc-name @p0' @p0=0x0001000000FFFFFFFF01000000000000000C02000000574E6574546F706F6C6F677953756974652C2056657273696F6E3D312E372E332E31373239382C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D663538306130353031366562616461310C030000004947656F4150492C2056657273696F6E3D312E312E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D6131613064613764656634363536373805010000002E4769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E506F696E74090000000B636F6F7264696E6174657308656E76656C6F70651047656F6D657472792B666163746F72791147656F6D657472792B75736572446174611147656F6D657472792B656E76656C6F70650D47656F6D657472792B737269641247656F6D657472792B64696D656E73696F6E1147656F6D657472792B626F756E646172791A47656F6D657472792B626F756E6461727944696D656E73696F6E040404020400040404404769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E436F6F7264696E617465417272617953657175656E6365020000001B47656F4150492E47656F6D6574726965732E49456E76656C6F706503000000384769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E47656F6D65747279466163746F7279020000001B47656F4150492E47656F6D6574726965732E49456E76656C6F706503000000081C47656F4150492E47656F6D6574726965732E44696D656E73696F6E73030000001B47656F4150492E47656F6D6574726965732E4947656F6D65747279030000001C47656F4150492E47656F6D6574726965732E44696D656E73696F6E73030000000200000009040000000A09050000000A0A0000000005FAFFFFFF1C47656F4150492E47656F6D6574726965732E44696D656E73696F6E73010000000776616C75655F5F000803000000000000000A01F9FFFFFFFAFFFFFF000000000504000000404769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E436F6F7264696E617465417272617953657175656E6365010000000B636F6F7264696E61746573041F47656F4150492E47656F6D6574726965732E49436F6F7264696E6174655B5D030000000200000009080000000505000000384769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E47656F6D65747279466163746F7279030000000E707265636973696F6E4D6F64656C19636F6F7264696E61746553657175656E6365466163746F72790473726964040400374769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E507265636973696F6E4D6F64656C02000000474769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E436F6F7264696E617465417272617953657175656E6365466163746F72790200000008020000000909000000090A000000000000000708000000000100000001000000041D47656F4150492E47656F6D6574726965732E49436F6F7264696E61746503000000090B0000000509000000374769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E507265636973696F6E4D6F64656C02000000096D6F64656C54797065057363616C6504002147656F4150492E47656F6D6574726965732E507265636973696F6E4D6F64656C7303000000060200000005F4FFFFFF2147656F4150492E47656F6D6574726965732E507265636973696F6E4D6F64656C73010000000776616C75655F5F000803000000000000000000000000000000050A000000474769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E436F6F7264696E617465417272617953657175656E6365466163746F72790000000002000000050B000000334769735368617270426C6F672E4E6574546F706F6C6F677953756974652E47656F6D6574726965732E436F6F7264696E6174650300000001780179017A000000060606020000000BEE77280AB404C0AD4D637B2DBA4940000000000000F8FF0B
可以看出,根据传递给
SetParameter()
并在命令中传递的内容确定的值是不同的


是否可以将类型传递给命名查询以执行我想要的操作?

我在检查了
NHibernate.type.IType
SetParameter()作为第三个参数的具体类型后,找到了它。以下作品

private static SqlGeography GetPoint(double latitude, double longitude)
{
    var geographyBuilder = new SqlGeographyBuilder();
    geographyBuilder.SetSrid(4326);
    geographyBuilder.BeginGeography(OpenGisGeographyType.Point);
    geographyBuilder.BeginFigure(latitude, longitude);
    geographyBuilder.EndFigure();
    geographyBuilder.EndGeography();
    return geographyBuilder.ConstructedGeography;
}

var query = Session.GetNamedQuery("my-sproc-name");

var point = GetPoint(latitude, longitude);
query.SetParameter(
    "Location", 
    point, 
    new NHibernate.Spatial.Type.SqlGeographyType());

// my-sproc-name is mapped to return a collection of EntityA types
query.List<EntityA>();
私有静态SqlGeography GetPoint(双纬度、双经度)
{
var geographyBuilder=新的SqlGeographyBuilder();
geographyBuilder.SetGrid(4326);
geographyBuilder.BeginGeography(OpenGisGeographyType.Point);
geographyBuilder.beginigure(纬度、经度);
geographyBuilder.EndFigure();
geographyBuilder.EndGeography();
返回geographyBuilder.ConstructedGeography;
}
var query=Session.GetNamedQuery(“我的存储过程名称”);
var点=获取点(纬度、经度);
query.SetParameter(
“地点”,
指向
新的NHibernate.Spatial.Type.SqlGeographyType());
//我的存储过程名称映射为返回EntityA类型的集合
query.List();
可以在程序集中找到
NHibernate.Spatial.Type.SqlGeographyType
类型