Сопоставление SqlGeography с Dapper

У меня есть сущность "Точка", которая содержит идентификатор, текст и географические координаты.

CREATE TABLE [Point] (
    [Id] INT IDENTITY CONSTRAINT [PK_Point_Id] PRIMARY KEY,
    [Coords] GEOGRAPHY NOT NULL,
    [Text] NVARCHAR(32) NOT NULL,
    [CreationDate] DATETIME NOT NULL,
    [IsDeleted] BIT NOT NULL DEFAULT(0)
)

CREATE PROCEDURE [InsertPoint]
    @text NVARCHAR(MAX),
    @coords GEOGRAPHY
AS BEGIN
    INSERT INTO [Point](Text, Coords, CreationDate)
    VALUES(@text, @coords, GETUTCDATE())    
    SELECT * FROM [Point] WHERE [Id] = SCOPE_IDENTITY()
END

Это ts sql код таблицы и хранимая процедура вставки. У меня есть класс для использования dapper:

public class DapperRequester : IDisposable {
    private readonly SqlConnection _connection;
    private SqlTransaction _transaction;

    public DapperRequester(string connectionString) {
        _connection = new SqlConnection(connectionString);
        _connection.Open();
    }
    public void Dispose() {
        _connection.Close();
    }

    public void BeginTransaction() {
        _transaction = _connection.BeginTransaction();
    }
    public void CommitTransaction() {
        _transaction.Commit();
    }
    public void RollbackTransaction() {
        _transaction.Rollback();
    }

    public void Query(string query, object parameters = null) {
        Dapper.SqlMapper.Execute(_connection, query, parameters, transaction: _transaction);
    }

    public void QueryProc(string procName, object parameters = null) {
        Dapper.SqlMapper.Execute(_connection, procName, parameters, commandType: CommandType.StoredProcedure, transaction: _transaction);
    }

    public IEnumerable<T> Execute<T>(string query, object parameters = null) {
        return Dapper.SqlMapper.Query<T>(_connection, query, parameters, transaction: _transaction);
    }

    public IEnumerable<dynamic> ExecuteProc(string procName, object parameters = null) {
        return Dapper.SqlMapper.Query(_connection, procName, parameters,
                                         commandType: CommandType.StoredProcedure, transaction: _transaction);
    }

    public IEnumerable<T> ExecuteProc<T>(string procName, object parameters = null) {
        return Dapper.SqlMapper.Query<T>(_connection, procName, parameters,
                                         commandType: CommandType.StoredProcedure, transaction: _transaction);
    }
}

С#-класс:

public class Point
{
    public int Id { get; set; }
    public SqlGeography Coords { get; set; }
    public string Text { get; set; }
}

И репозиторий имеет метод

public Point InsertPoint(string text, SqlGeography coords)
    {
        using (var requester = GetRequester())
        {
            return requester.ExecuteProc<Point>("InsertPoint", new { text, coords }).FirstOrDefault();
        }
    }

Когда я использую такую ​​систему для любого другого класса, все в порядке, но есть проблема с отображением, я думаю, это из-за типа SqlGeography. Использование:

SqlGeography coords = new SqlGeography();
        coords = SqlGeography.Point(10.5, 15.5, 4326);
        Point point = new Point { Coords = coords, Text = "Text" };
        point = Repositories.PointRepository.InsertPoint(point.Text, point.Coords);

И у меня есть исключение The member coords of type Microsoft.SqlServer.Types.SqlGeography cannot be used as a parameter value

Есть ли какой-то секрет отображения этого типа?


person lenden    schedule 23.08.2012    source источник


Ответы (3)


Dapper 1.32 теперь comment39884016_25542766">включает прямую поддержку этого. Теперь ваш код должен просто работать.

person Marc Gravell    schedule 28.08.2014
comment
Он также должен работать с QueryMultiple? Я получаю сообщение об ошибке синтаксического анализа столбца 5 при выполнении reader.Read. А столбец 5 — это полигон SqlGeography. - person Andrew Savinykh; 28.07.2015
comment
Будьте осторожны, чтобы использовать правильную версию SqlGeography в зависимости от используемой версии базы данных ms. Мне пришлось установить SqlGeography версии 10.5 для Sql 2012. Тогда с Dapper все заработало. - person mac10688; 15.04.2016

Dapper не поддерживает определенные типы данных поставщика БД. В вашем случае это ГЕОГРАФИЯ.

Dapper не имеет конкретных деталей реализации БД, он работает со всеми поставщиками .net ado, включая sqlite, sqlce, firebird, oracle, MySQL и SQL Server.

Чтобы обработать этот параметр с помощью Dapper, вам придется написать для него собственную обработку. Например, см. этот ответ.

Удачи

person Void Ray    schedule 23.08.2012

Я столкнулся с похожей проблемой. Я обнаружил, что Dapper прекрасно сопоставляет результирующие поля с Microsoft.SqlServer.Types.SqlGeography, но использование их в качестве параметров не работает.

Я изменил файл SqlMapper.cs, чтобы включить поддержку этого типа. Вы можете увидеть Gist здесь: https://gist.github.com/bmckenzie/4961483

Нажмите «Редакции», чтобы увидеть, что я изменил.

person Brendan    schedule 15.02.2013