使用Dapper和SQL Spatial Types作为参数

Eri*_*kel 8 orm spatial sql-server-2008 dapper

我有一个基本上必须做这样的查询的系统:

SELECT * FROM MyTable WHERE @parameter.STIntersects(MyGeometryColumn)
Run Code Online (Sandbox Code Playgroud)

使用vanilla SQL参数时这很简单,你只需要以非典型的方式创建参数(其中builder变量是我用来创建矩形的SqlGeometryBuilder):

command.Parameters.Add(new SqlParameter
{
    UdtTypeName = "geometry",
    Value = builder.ConstructedGeometry,
    ParameterName = "@paremeter"
});
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试使用dapper这样做时,我得到一个错误,它无法弄清楚如何将其用作参数.任何有这个工作的人,或者有关如何启用此功能的任何指示?我有一个解决方法,但这涉及使用字符串表示并将其转换为我的SQL查询中的几何类型.我真的不想那样.

要回答评论,我得到的错误是'Microsoft.SqlServer.Types.SqlGeometry类型的成员参数不能用作参数值'.换句话说,dapper不知道如何将SqlGeometry对象作为参数处理.

Sam*_*ron 10

实现奇怪和精彩的数据库特定参数的关键所有归结为 SqlMapper.IDynamicParameters

这个简单的界面有一个端点:

public interface IDynamicParameters
{
    void AddParameters(IDbCommand command);
}
Run Code Online (Sandbox Code Playgroud)

Dapper已经有一个名为的接口的数据库通用实现:DynamicParameters它允许您处理输出和返回值.

要模仿这些空间的东西,我会尝试类似的东西:

public class SpatialParam : SqlMapper.IDynamicParameters
{
    string name; 
    object val;

    public SpatialParam(string name, object val)
    {
       this.name = name; 
       this.val = val;
    }

    public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
    {
       var sqlCommand = (SqlCommand)command;
       sqlCommand.Parameters.Add(new SqlParameter
       {
          UdtTypeName = "geometry",
          Value = val,
          ParameterName = name
       });
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

cnn.Query("SELECT * FROM MyTable WHERE @parameter.STIntersects(MyGeometryColumn)",
  new SpatialParam("@parameter", builder.ConstructedGeometry));
Run Code Online (Sandbox Code Playgroud)

这个简单的接口实现只处理一个参数,但它可以很容易地扩展到处理多个参数,可以通过从构造函数传入或添加一个帮助器AddParameter方法.


Bre*_*dan 5

如果您不介意修改Dapper的核心,那么您可以使用我所做的... https://gist.github.com/brendanmckenzie/4961483

我修改了Dapper以接受Microsoft.SqlServer.Types.SqlGeography参数.