使用Dapper映射SqlGeography

我有实体“点”,包含Id,文本和地理坐标。

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 

这是表的sql代码和插入的存储过程。 我有使用短小精悍的课程:

 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 Execute(string query, object parameters = null) { return Dapper.SqlMapper.Query(_connection, query, parameters, transaction: _transaction); } public IEnumerable ExecuteProc(string procName, object parameters = null) { return Dapper.SqlMapper.Query(_connection, procName, parameters, commandType: CommandType.StoredProcedure, transaction: _transaction); } public IEnumerable ExecuteProc(string procName, object parameters = null) { return Dapper.SqlMapper.Query(_connection, procName, parameters, commandType: CommandType.StoredProcedure, transaction: _transaction); } } 

c#-class是:

 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("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

是否存在映射该类型的秘密?

Dapper 1.32现在包括对此的直接支持 。 您的代码现在应该可以正常运行

Dapper不支持DB Provider特定的数据类型。 在你的情况下它的地理。

Dapper没有特定于DB的实现细节,它适用于所有.net ado提供程序,包括sqlite,sqlce,firebird,oracle,MySQL和SQL Server

为了使用Dapper处理这个参数,你必须为它编写自己的处理。 例如,请参阅此答案 。

祝好运

我遇到了类似的问题。 我发现Dapper会将结果字段映射到Microsoft.SqlServer.Types.SqlGeography就好了,但是使用它们作为参数不起作用。

我修改了SqlMapper.cs文件以包含对此类型的支持。 你可以在这里看到Gist: https : //gist.github.com/bmckenzie/4961483

单击“修订”以查看我更改的内容。