2012-08-23 17 views
8

ID、テキスト、地理座標を含むエンティティ "Point"があります。Dapperを使用したSqlGeographyのマッピング

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<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です:私はDapperの使用のためのクラスが持つ

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

ダッパー1.32 now includes direct support for this。あなたのコードは今すぐを処理する必要があります。

+0

また、QueryMultipleを使用する予定ですか? reader.Readを実行しているときに、「5列の解析中にエラーが発生しました。列5はSqlGeographyポリゴンです。 –

+1

使用しているmsデータベースのバージョンに応じて、正しいバージョンのSqlGeographyを使用するように注意してください。私はSql 2012用SqlGeography Version 10.5をインストールしなければなりませんでした。 – mac10688

1

Dapperは、DBプロバイダ固有のデータ型をサポートしていません。あなたのケースでは、その地理。

Dapperのは、それが全体に動作しますが、何のDB固有の実装の詳細を持っていないすべての .NET ADOのsqlite、SQLCE、Firebirdの、オラクル、MySQLの やSQL Serverなどのプロバイダでこれのparamを扱うために

Dapper、あなたはそれのためにあなた自身の取り扱いを書く必要があります。例については、answerを参照してください。

幸運

1

私は同様の問題に遭遇しました。私はDapperが結果フィールドをMicrosoft.SqlServer.Types.SqlGeographyにマップすることがわかりましたが、それらをパラメータとして使用しても機能しませんでした。

このタイプのサポートを含めるようにSqlMapper.csファイルを変更しました。ここで要点を見ることができます:https://gist.github.com/bmckenzie/4961483

私が変更した内容を見るには、「リビジョン」をクリックしてください。

関連する問題