2012-08-23 65 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

點擊「修訂」看看我改變了什麼。