Использование Dapper с пространственными типами SQL в качестве параметра - PullRequest
8 голосов
/ 14 июля 2011

У меня есть система, которая в основном должна делать запрос, подобный этому:

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

Это довольно просто сделать при использовании ванильных параметров SQL, вам просто нужно создать свой параметр нестандартным способом (где переменная построителя - это SqlGeometryBuilder, который я использую для создания прямоугольника):

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

Теперь, когда я пытаюсь сделать это с помощью dapper, я получаю сообщение об ошибке, что не могу понять, как использовать это в качестве параметра. Кто-нибудь, у кого это работает, или какие-нибудь указатели о том, как включить это? У меня есть обходной путь, но он включает использование строкового представления и преобразование его в тип геометрии в моем запросе SQL. Я действительно не хочу этого.

Чтобы ответить на комментарий, я получаю сообщение об ошибке: «Параметр-член типа Microsoft.SqlServer.Types.SqlGeometry не может использоваться в качестве значения параметра». Другими словами, dapper не знает, как обращаться с объектом SqlGeometry в качестве параметра.

Ответы [ 3 ]

10 голосов
/ 15 июля 2011

Ключ к реализации странных и замечательных параметров, специфичных для БД, сводится к SqlMapper.IDynamicParameters

Этот простой интерфейс имеет единственную конечную точку:

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

У 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
       });
    }
}

Использование:

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

Эта простая реализация интерфейса обрабатывает только одинparam, но его можно легко расширить для обработки нескольких параметров, передавая из конструктора или добавляя вспомогательный метод AddParameter.

5 голосов
/ 15 февраля 2013

Если вы не возражаете модифицировать Dapper по своей сути, тогда вы можете использовать то, что я сделал ... https://gist.github.com/brendanmckenzie/4961483

Я изменил Dapper для принятия Microsoft.SqlServer.Types.SqlGeography параметров.

2 голосов
/ 28 августа 2014
  • Dapper.EntityFramework 1.26 поддерживает DbGeography
  • Dapper 1.32 имеет встроенную поддержку SqlGeography
  • Dapper 1.33 имеет встроенную поддержку SqlGeometry
  • Dapper.EntityFramework 1.33 имеет встроенную поддержку DbGeometry
  • Dapper 1.34 имеет встроенную поддержку SqlHierarchyId

Так с последними библиотеками; это должно просто работать.

...