私はMicrosoft.SqlServer.Types.dll
WPF および ASP.NET アプリでSqlGeometry
タイプおよび空間クエリを何年も (v.10 以降)使用してきましSqlServerSpatialXXX.dll
たMicrosoft.SqlServer.Types.dll
。
SqlGeometry
型は、SqlGeography
を参照することで VS プロジェクト (C# など) で使用できますMicrosoft.SqlServer.Types.dll
。
Microsoft.SqlServer.Types.dll
管理されたライブラリであり、前提条件としていくつかの管理されていないライブラリがあり、それらはSqlServerSpatialXXX.dllおよびmsvcrXXX.dllのようなものです
- Sql Server 2008 以降、さまざまなバージョンの
Microsoft.SqlServer.Types.dll
が利用可能になっていますが、2012 年以降の機能の変更は見られません。
64 ビット/32 ビットの問題を考慮する
- 64 ビット マシンの場合、Sql Server の CLR タイプをインストールすると、これらの前提条件ファイルの 64 ビット バージョンがWindows/System32にあり、32 ビット バージョンの前提条件ファイルがWindows/SysWOW64フォルダーにあります。
- CLR 型がマシンにインストールされていない場合は、プロジェクト (32 ビットまたは 64 ビット) に基づいてこれらの前提条件の適切なバージョン (32 ビット/64 ビット) を手動でロードする必要があります。そうしないと、次のようなエラーが発生します。
SqlServerSpatialXXX.dll の読み込みエラー
を使用して、C# で実行時に 32 ビット/64 ビットの問題を確認できますEnvironment.Is64BitProcess
。サンプルコードは次のとおりです。
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibrary(string libname);
private static void LoadNativeAssembly(string nativeBinaryPath, string assemblyName)
{
var path = Path.Combine(nativeBinaryPath, assemblyName);
if (!File.Exists(path))
{
throw new FileNotFoundException($"{path} not found");
}
var ptr = LoadLibrary(path);
if (ptr == IntPtr.Zero)
{
throw new Exception(string.Format(
"Error loading {0} (ErrorCode: {1})",
assemblyName,
Marshal.GetLastWin32Error()));
}
}
public static void LoadNativeAssembliesv13(string rootApplicationPath)
{
var nativeBinaryPath = Environment.Is64BitProcess
? Path.Combine(rootApplicationPath, @"SqlServerTypes\x64\")
: Path.Combine(rootApplicationPath, @"SqlServerTypes\x86\");
LoadNativeAssembly(nativeBinaryPath, "msvcr120.dll");
LoadNativeAssembly(nativeBinaryPath, "SqlServerSpatial130.dll");
}
プロジェクトの種類ごとにバイナリ パスを検討する プロジェクトの実行パスには、次のようにSqlServerTypes
という名前のフォルダーを作成することをお勧めします。
SqlServerTypes>x64
SqlServerTypes>x32
このようにアンマネージアセンブリをロードします
Utilities.LoadNativeAssembliesv13(Environment.CurrentDirectory); //WPF
Utilities.LoadNativeAssembliesv13(HttpRuntime.BinDirectory); //ASP.NET
ADO.NET を使用して Sql Server から SqlGeometry を読み取る際の問題 使用して
いるバージョンに関係なく、ADO.NET を使用して Sql Serverからそれらを読み取ろMicrosoft.SqlServer.Types.dll
うとすると、キャスト例外が発生する可能性があります。これは、SQL クライアントがデフォルトでバージョン 10.0.0.0 をロードするためです。の。この場合、数年前に私は WKB (アプローチ 1 と 2) と WKTを異なるバージョンの型の間で変換するための媒体として試してみました。使用しているバージョンをロードし、単純なキャストを使用して取得できます(アプローチ 3)Microsoft.SqlServer.Types.dll
SqlGeometry
Microsoft.SqlServer.Types.dll
SqlGeometry
private List<SqlGeometry> SelectGeometries(string connectionString)
{
SqlConnection connection = new SqlConnection(connectionString);
var command = new SqlCommand(select shapeCol from MyTable, connection);
connection.Open();
List<SqlGeometry> geometries = new List<SqlGeometry>();
SqlDataReader reader = command.ExecuteReader();
if (!reader.HasRows)
{
return new List<SqlGeometry>();
}
while (reader.Read())
{
//approach 1: using WKB. 4100-4200 ms for hundred thousands of records
//geometries.Add(SqlGeometry.STGeomFromWKB(new System.Data.SqlTypes.SqlBytes((byte[])reader[0]), srid).MakeValid());
//approach 2: using WKB. 3220 ms for hundred thousands of records
//geometries.Add(SqlGeometry.Deserialize(reader.GetSqlBytes(0)));
//approach 3: exception occur if you forget proper assembly redirection. 2565 ms for hundred thousands of records
geometries.Add((SqlGeometry)reader[0]);
}
connection.Close();
return geometries;
}