2012-08-23 3 views
8

ID, 텍스트 및 지리 좌표가 포함 된 엔티티 "포인트"가 있습니다.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 코드를 삽입하는 프로 시저의 TS. 내가 날씬한 사용하는 클래스가 :

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

대퍼 1.32 지금 includes direct support for this. 귀하의 코드는 이제 일을해야합니다.

+0

QueryMultiple에서도 사용할 수 있습니까? reader.Read를 할 때 "Error parsing column 5"가 표시됩니다. 열 5는 SqlGeography 다각형입니다. –

+1

사용중인 ms 데이터베이스 버전에 따라 올바른 버전의 SqlGeography를 사용하십시오. Sql 2012에 SqlGeography 버전 10.5를 설치해야했습니다. 그런 다음 Dapper와 잘 작동했습니다. – mac10688

1

Dapper는 DB 공급자 특정 데이터 형식을 지원하지 않습니다. 귀하의 경우 지리적 위치.

단정 한 그것은에서 작동, 어떤 DB 특정 구현 세부 사항이없는 모든 .NET ADO SQLite는, SQLCE, 파이어 버드, 오라클, MySQL을 및 SQL Server를 포함한 공급자와이 PARAM을 처리하기 위해

Dapper, 당신은 그것을위한 당신의 자신의 취급을 써야 할 것입니다. 예를 들어,이 answer을 참조하십시오.

행운

1

나는 비슷한 문제로 실행했습니다. 나는 Dapper가 결과 필드를 Microsoft.SqlServer.Types.SqlGeography에 매핑하는 것을 알았지 만, 매개 변수로 사용하는 것은 효과가 없었습니다.

이 유형의 지원을 포함하도록 SqlMapper.cs 파일을 수정했습니다. 요점을 여기에서 볼 수 있습니다 : https://gist.github.com/bmckenzie/4961483

내가 무엇을 변경했는지 보려면 "개정"을 클릭하십시오.