22

Sql 2008 GeographyタイプでNhibernateを使用しようとしていますが、問題が発生しています。私はFluentNhibernateを使用して、かなり新しい設定を行っているので、それも問題になる可能性があります。

まず、私が永続化しようとしているクラスは次のようになります。

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;}
}

マッピングクラスは次のようになります。

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

Fluent NhibernateでMsSql2008GeographyDialectを使用するために、独自の構成クラスを作成しました。

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

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

だから私は次のような構成コードを持っています:

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

LocationLogタイプをデータベースに永続化しようとすると、次のエラーが発生するという事実を設定するために、これらすべてを実行します。

ユーザー定義ルーチンまたは集約"geography"の実行中に.NETFrameworkエラーが発生しました:System.ArgumentException:24204:空間参照識別子(SRID)が無効です。指定されたSRIDは、sys.spatial_reference_systemsカタログビューに表示されるサポートされているSRIDの1つと一致する必要があります。System.ArgumentException:at Microsoft.SqlServer.Types.SqlGeography.set_Srid(Int32 value)at Microsoft.SqlServer.Types.SqlGeography.Read(BinaryReader r)at SqlGeography ::。DeserializeValidate(IntPtr、Int32、CClrLobContext *)

Nhibernate Spatialライブラリを構成および使用する方法について、次の記事を読みました。

しかし、どちらも役に立たないようです。洞察を提供できるSpatialGeographyタイプを使用するようにNhibernateを構成した経験のある人なら誰でも大歓迎です。

4

5 に答える 5

10

私は同じ船に乗っています、そしてあなたのスタートのおかげで私はそれを動かしました(空間データの挿入と読み取り)。興味のある他の人のために、最初にGisSharpBlog.NetTopologySuite.Geometries.PointクラスはnHibernate.Spatialダウンロードの一部であるNetTopologySuite.dllにあります。

次に、Jamesポイントに従って、SRIDを4326に設定していることを確認します。

そして最後に、マップは次のようになっている必要があります。

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

私はGeographyを使用していますが、GeometryTypeを使用すると機能する可能性があり、それが機能することをどこかで読みました(いくつかのポイントを挿入し、データベースで検証しました)。また、(Criteriaを使用するのではなく)特別なSQL 2008 Spatialメソッドを使用できるように、地理用のSQLクエリを作成するのが最善であることも読みました。

于 2010-10-25T04:40:30.407 に答える
2

スティーブは正しいです。ジオメトリタイプのSRIDを明示的に設定する必要があります。NHibernate.Spatialソース(SVNなどを使用してチェックアウトできます)を見ると、SRIDを検索すると、コメントのヒントとしてコードに埋め込まれていることがわかります。

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

SRIDという名前のパラメーターを必要な数に設定する必要があるようです(SRIDテーブルで検索してください)。明らかにこれは昔ながらのXML構成ですが、Fluentには、キー/値の文字列パラメーターを追加するメソッドがどこかにあります。それを試してみてください。


編集

もう少し調べてみると、列にsrid属性を設定しようとすると、NHibernateのXMLマッピング検証に失敗し、XmlSchemaValidationExceptionがスローされることがわかりました。代わりに、NetNopologySuiteのジオメトリタイプにはオブジェクト自体にSRID属性があり、これを設定すると機能することがわかりました。例えば

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

これを行うにはもっと良い方法があるはずです(常に設定するのではなく構成する)が、私はまだそれを解決していません。MsSql2008GeometryTypeクラスの内部を見ると、SetDefaultSRID(IGeometry)と呼ばれる保護されたメソッドがあります-理由があるはずです!

于 2009-11-24T21:37:45.713 に答える
1

私はこれがほとんど役に立たないことを知っていますが、とにかく。すべてのlainを実装した後、HQLクエリでSetParameterの3番目のITypeパラメーターを使用すると言っていました。の意味

 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();

new CustomType(typeof(MsSql2008GeographyType)、null)を渡す必要があります。そうしないと、使い慣れた「System.ArgumentException:24204」が発生します。

それを理解するために一晩中過ごしました。

于 2012-03-04T02:12:57.973 に答える
1

実際には答えではなく質問です;-)

  • GisSharpBlog.NetTopologySuite.Geometries.PointオブジェクトにSRIDを設定していますか?

デフォルト(ポイントはジオメトリであるため)は0であり、LocationLog.Locationプロパティを地理として永続化しようとするとSQLエラーが発生します。0はSQL地理フィールドの有効なSRIDではありません。sys.spatial_reference_systemsビューから指定する必要があります。

  • Fluent NHibernateなしで試しましたか?

問題からできるだけ多くのコンポーネントを排除するため。

于 2009-10-07T07:55:26.397 に答える
1

デフォルトのSRIDを使用して独自のファクトリを作成できます。たとえば、次のような工場のファサードを作成できます。

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

    public static readonly IGeometryFactory Factory;

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

次のように使用します。

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

「new」キーワードを使用する代わりに。IoCフレームワークのファクトリメソッドとしてDefault.Factoryを使用して、デフォルトのファサードなしで新しいジオメトリを作成することもできます。

于 2011-04-20T14:14:33.820 に答える