NHibernate.Spatial and SQL 2008 Geografia Typ-Jak skonfigurować

Próbuję używać Nhibernate z typem SQL 2008 i mam trudności. Używam Fluent NHibernate do konfiguracji, którą jestem dość nowy, więc może to być również problem.

Po pierwsze, klasa, którą staram się utrzymać wygląda mniej więcej tak:

public class LocationLog : FluentNHibernate.Data.Entity
{
   public virtual new int Id {get;set;}
   public virtual DateTime TimeStamp {get;set;}
   public virtual GisSharpBlog.NetTopologySuite.Geometries.Point Location {get;set;}
}

Klasa mapowania wygląda następująco:

public class LocationLogMap : ClassMap<LocationLog>
{
   ImportType<GisSharpBlog.NetTopologySuite.Geometries.Point>();
   Id(x => x.Id);
   Map(x => x.TimeStamp).Generated.Insert();
   Map(x => x.Location);
}

W celu korzystania z MsSql2008GeographyDialect z Fluent Nhibernate, stworzyłem własną klasę konfiguracji:

public class Sql2008Configuration
  : PersistenceConfiguration<Sql2008Configuration, MsSqlConnectionStringBuilder>
{
   public Sql2008Configuration()
   {
      Driver<SqlClientDriver>();
   }

   public static Sql2008Configuration MsSql2008
   {
      get { return new Sql2008Configuration().Dialect<MsSql2008GeographyDialect>(); }
   }
}

Więc mam konfigurację kod podobny:

var configuration = Fluently.Configure()
  .Database(Sql2008Configuration.MsSql2008.ConnectionString(c => c.Is(connectionString)))
  .Mappings(m => m.FluentMappings
    .AddFromAssemblyOf<LocationLog>()
);

Wszystko po to, aby ustawić fakt, że podczas próby persist typu LocationLog do bazy danych otrzymuję następujący błąd:

Błąd. NET Framework wystąpił podczas wykonanie zdefiniowanej przez użytkownika procedury lub Agregaty " Geografia": System.Wyswietlen: 24204 spatial reference identifier (srid) to nieważne. Określony SRID musi dopasuj jeden z obsługiwanych Srid wyświetlane w sys.katalog spatial_reference_systems widok. System.ArgumentException: at Microsoft.SqlServer.Typy.SqlGeography.set_Srid(Int32 wartość) w Microsoft.SqlServer.Typy.SqlGeography.Read(BinaryReader r) w SqlGeography.::.DeserializeValidate(IntPtr , Int32, CClrLobContext*)

Przeczytałem następujące artykuły o tym, jak skonfigurować i używać NHibernate Spatial biblioteki:

Ale żadne z nich nie pomaga. Każdy, kto ma doświadczenie w konfigurowaniu Nhibernate do korzystania z typów geografii przestrzennej, który mógłby dostarczyć wszelkich spostrzeżeń, byłby bardzo mile widziany.
Author: hazzik, 2009-09-30

5 answers

Jestem w tej samej łodzi i dzięki Twojemu startowi udało mi się ją uruchomić (wstawianie i odczyt danych przestrzennych). Dla wszystkich zainteresowanych przede wszystkim gissharpblog.NetTopologySuite.Geometrie.Klasa punktowa znajduje się w NetTopologySuite.dll, który jest częścią nHibernate.Spatial download.

Po drugie, zgodnie z punktem Jamesa, upewnij się, że ustawiłeś SRID na 4326.

I na koniec mapa musi wyglądać tak:

Map(a => a.Location).CustomType(typeof(NHibernate.Spatial.Type.GeometryType));

Używam geografii, ale gdzieś czytałem, że używając GeometryType może działać i działa dla mnie (wstawiłem kilka punktów i zweryfikowałem je w bazie danych). Czytałem też, że najlepiej jest pisać zapytania SQL dla geografii, aby można było użyć specjalnych metod przestrzennych SQL 2008 (w przeciwieństwie do korzystania z kryteriów).

 10
Author: Iain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-25 04:40:30

Steve ma rację, musisz jawnie ustawić SRID dla swojego typu geometrii. Patrzę na NHibernate.Spatial source (które możesz sprawdzić używając SVN lub cokolwiek innego), szukając SRID pojawia się z tym zakopanym w kodzie jako podpowiedź komentarza:

<class name="MyGeoTableA">
    <property name="MyGeoColumn">
        <type name="NHibernate.Spatial.Type.GeometryType, NHibernate.Spatial">
            <param name="srid">1234</param>
        </type>
    </property>
</class>

Wygląda na to, że musisz ustawić parametr o nazwie SRID na dowolną liczbę (poszukaj go w tabeli SRID). Oczywiście jest to old-school konfiguracja XML ale fluent będzie miał metodę gdzieś dodać parametry łańcuchowe klucza/wartości. Spróbuj.


Edit

Po nieco dalszych badaniach odkryłem, że próba ustawienia atrybutu srid na kolumnie nie powiodła się walidacji mapowania XML NHibernate, rzuca wyjątek XmlSchemaValidationException. Zamiast tego odkryłem, że typy geometrii w NetNopologySuite mają atrybut srid na samym obiekcie, a ustawienie tego sprawia, że wszystko działa. np.

LocationLog log = new LocationLog { Location = new Point() };
log.Location.SRID = 4326;
Session.Save(log);

Musi być lepszy sposób, aby to zrobić (skonfiguruj go zamiast ustawianie go cały czas), ale jeszcze tego nie rozgryzłem. Jeśli zajrzysz do klasy MsSql2008GeometryType, ma ona chronioną metodę o nazwie SetDefaultSRID ( IGeometry) - musi tam być nie bez powodu!

 2
Author: James Allen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-04 15:11:50

Nie do końca odpowiedź, ale pytania; -)

  • czy ustawiasz SRID na GisSharpBlog.NetTopologySuite.Geometrie.Punkt obiekt?

Domyślną wartością (ponieważ punkt jest geometrią) jest 0 i spowoduje błąd SQL podczas próby utrzymania LocationLog.Lokalizacja nieruchomości jako Geografia. 0 nie jest poprawnym SRID dla pól geograficznych sql. Musisz podać jeden z sys.widok spatial_reference_systems.

  • Czy próbowałeś bez biegłości NHibernate?

Aby wyeliminować jak najwięcej komponentów z problemu.

 1
Author: Steve Casey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-07 07:55:26

Możesz utworzyć własną fabrykę z domyślnym SRID. Na przykład, można utworzyć fasadę dla fabryk, takich jak:

public static class Default
{
    private const int DefaultSrid = 4326;

    public static readonly IGeometryFactory Factory;

    static Default()
    {
        Factory = new GeometryFactory(new PrecisionModel(), DefaultSrid);
    }
}

I użyj go tak:

var point = Default.Factory.CreatePoint(new Coordinate(10, 10));

Zamiast używać słowa kluczowego "nowy". Można również użyć domyślnego.Factory jako metoda fabryczna w ramach IoC do tworzenia nowych geometrii bez domyślnej fasady.

 1
Author: Matan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-20 14:14:33

Wiem, że to mało przydatne, ale w każdym razie. Po zaimplementowaniu wszystkich lain powiedział używać w zapytaniach HQL SetParameter trzeci parametr IType. Znaczenie w

 Hero hero = openSession.Get<Hero>(3);    
openSession.CreateQuery(
              "from Hero h where NHSP.Distance(h.Location,:thislocation)<1000"
               ).SetParameter("thislocation", hero.Location, new CustomType(typeof(MsSql2008GeographyType), null) ).SetResultTransformer(new DistinctRootEntityResultTransformer())
               .List();

Nowy CustomType(typeof (MsSql2008GeographyType), null) musi zostać przekazany, w przeciwnym razie otrzymasz system "all too familar".Wyswietlen: 24204

Spędziłem całą noc, zastanawiając się nad tym.
 1
Author: opcheese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-04 02:12:57