使用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
单击“修订”以查看我更改的内容。