2011-07-14 12 views
8

Mam system, który w zasadzie ma zrobić kwerendę tak:Korzystanie Dapper z typami SQL Przestrzennych jako parametr

SELECT * FROM MyTable WHERE @parameter.STIntersects(MyGeometryColumn) 

Jest to dość proste do zrobienia przy użyciu parametrów wanilia SQL, wystarczy aby utworzyć parametr w nietypowym sposób (gdzie zmienna Builder jest SqlGeometryBuilder którego używam, aby utworzyć prostokąt):

command.Parameters.Add(new SqlParameter 
{ 
    UdtTypeName = "geometry", 
    Value = builder.ConstructedGeometry, 
    ParameterName = "@paremeter" 
}); 

teraz, gdy próbuję to zrobić za pomocą elegancki, pojawia się błąd, że nie może dowiedzieć się, jak użyć tego jako parametru. Każdy, kto ma to działa, lub jakieś wskazówki, jak to włączyć? Mam obejście, ale wymaga to użycia reprezentacji ciągów i przekonwertowania tego do typu geometrii w mojej kwerendzie SQL. Naprawdę nie chcę tego.

Aby odpowiedzieć na komentarz, wyświetlany jest błąd "Parametr członka typu Microsoft.SqlServer.Types.SqlGeometry nie może być użyty jako wartość parametru". Innymi słowy, dapper nie wie, jak traktować obiekt SqlGeometry jako parametr.

+0

Jaki jest błąd, który otrzymujesz? –

Odpowiedz

10

Kluczem do realizacji dziwne i cudowne DB konkretnych params wszystko sprowadza się do SqlMapper.IDynamicParameters

Ten prosty interfejs ma pojedynczy punkt końcowy:

public interface IDynamicParameters 
{ 
    void AddParameters(IDbCommand command); 
} 

Wytworny ma już DB rodzajowego wdrożenia tego interfejsu o nazwie: DynamicParameters, który umożliwia obsługę wartości wyjściowych i zwracanych.

naśladować te rzeczy przestrzennej chciałbym spróbować czegoś takiego:

public class SpatialParam : SqlMapper.IDynamicParameters 
{ 
    string name; 
    object val; 

    public SpatialParam(string name, object val) 
    { 
     this.name = name; 
     this.val = val; 
    } 

    public void AddParameters(IDbCommand command, SqlMapper.Identity identity) 
    { 
     var sqlCommand = (SqlCommand)command; 
     sqlCommand.Parameters.Add(new SqlParameter 
     { 
      UdtTypeName = "geometry", 
      Value = val, 
      ParameterName = name 
     }); 
    } 
} 

Zastosowanie:

cnn.Query("SELECT * FROM MyTable WHERE @parameter.STIntersects(MyGeometryColumn)", 
    new SpatialParam("@parameter", builder.ConstructedGeometry)); 

Ta prosta implementacja interfejsu obsługuje tylko pojedynczy param, ale można go łatwo być rozszerzony, aby obsłużyć wiele parametrów, albo przez przekazanie od konstruktora lub dodanie metody AddParameter helpera.

+0

Działa doskonale!Dzięki :) –

+0

UWAGA: Obecna wersja Dappera (jak pisałem ten komentarz) ma nieco inny podpis metody interfejsu, teraz => void AddParameters (IDbCommand command, SqlMapper.Identity identity) –

1
  • Dapper.EntityFramework 1,26 obsługuje DbGeography
  • Dapper 1.32 posiada wbudowany wsparcie SqlGeography
  • Dapper 1.33 posiada wbudowaną obsługę SqlGeometry
  • Dapper.EntityFramework 1.33 posiada wbudowaną obsługę DbGeometry
  • Dappera 1.34 ma wbudowaną obsługę dla SqlHierarchyId

Tak więc z najnowszymi bibliotekami; powinien po prostu działać.

Powiązane problemy