2012-08-23 69 views
8

我有实体“点”,其中包含Id,文本和地理坐标。映射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代码表和存储过程的插入。我有类使用短小精悍:

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

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

是否有一些映射该类型的秘密?

回答

9

Dapper 1.32 now includes direct support for this。你的代码现在应该只是工作

+0

它是否也应该与QueryMultiple一起使用?阅读时出现“解析第5列”错误。第5列是一个SqlGeography多边形。 –

+1

请注意根据您使用的ms数据库版本使用正确版本的SqlGeography。我必须为Sql 2012安装SqlGeography Version 10.5。然后,它与Dapper一起运行良好。 – mac10688

1

Dapper不支持数据库提供程序特定的数据类型。在你的情况下,它的地理。

小巧玲珑没有DB具体的实施细则,它工作在所有 .NET ADO提供商,其中包括sqlite的,SQLCE,火鸟,Oracle,MySQL等 和SQL Server

为了处理这个PARAM用Dapper,你将不得不为自己编写处理程序。有关示例,请参阅此answer

祝你好运

1

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

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

点击“修订”看看我改变了什么。