11

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

これは、テーブルのtssqlコードと挿入のストアドプロシージャです。私はdapperを使用するためのクラスを持っています:

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#-クラスは:

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

そのタイプをマッピングする秘訣はありますか?

4

3 に答える 3

14

Dapper 1.32には、これを直接サポートするようになりました。これで、コードは単純に機能するはずです。

于 2014-08-28T08:31:11.347 に答える
1

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

DapperにはDB固有の実装の詳細はなく、sqlite、sqlce、firebird、oracle、MySQL、SQLServerを含むすべての.netadoプロバイダーで機能します。

このパラメータをDapperで処理するには、独自の処理を作成する必要があります。例については、この回答を参照してください。

幸運を

于 2012-08-23T16:55:46.270 に答える
1

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

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

「改訂」をクリックして、変更内容を確認してください。

于 2013-02-15T16:27:13.710 に答える