8

我有一个系统,它基本上必须执行这样的查询:

SELECT * FROM MyTable WHERE @parameter.STIntersects(MyGeometryColumn)

这在使用普通 SQL 参数时非常简单,您只需以非典型方式创建参数(其中 builder 变量是我用来创建矩形的 SqlGeometryBuilder):

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

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

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

4

3 回答 3

10

实现奇怪而美妙的 DB 特定参数的关键都归结为SqlMapper.IDynamicParameters

这个简单的接口有一个端点:

public interface IDynamicParameters
{
    void AddParameters(IDbCommand command);
}

Dapper 已经有了这个接口的 DB 通用实现,称为: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
       });
    }
}

用法:

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

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

于 2011-07-14T23:46:43.020 回答
5

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

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

于 2013-02-15T16:28:30.467 回答
3
  • Dapper.EntityFramework 1.26 支持DbGeography
  • Dapper 1.32 内置支持SqlGeography
  • Dapper 1.33 内置支持SqlGeometry
  • Dapper.EntityFramework 1.33 内置支持DbGeometry
  • Dapper 1.34 内置支持SqlHierarchyId

因此,使用最新的库;它应该可以正常工作。

于 2014-08-28T08:55:50.873 回答