无法加载SqlServerSpatial.dll

VBA*_*ole 31 .net c# sql-server clr geospatial

我试图在C#.Net项目中使用SqlServer Spatial CLR类型.我想使用SqlGeometry来查询我的数据库中的空间记录.

我在本地计算机上运行Visual Studio 2010中运行的单元测试,命中远程SqlServer计算机.都好.

然后,我将WCF Rest服务发布到我的本地IIS实例,该实例具有与单元测试匹配相同类库的服务,以进行一些空间查询,并且失败.

我收到一个错误说

无法加载DLL SqlServerSpatial.dll:找不到指定的模块.

我用谷歌搜索了这个并找到了许多答案 - 对我来说都没有用.我有:

  • 在GAC中注册了CLR类型
  • 安装64位,后来也安装了32位版本的VC++
  • 尝试了使用不同的Microsoft.SqlServer.Types dll版本的许多变体

我唯一没做过的,坦率地拒绝做的是在实际的SqlServer盒子上安装任何东西.这对我来说似乎没用.

在这一点上,我唯一能想到的是导致这是一个权限问题,因为它在IIS应用程序池中运行,而不是在单元测试中工作的Studio内部.

请注意,在我的项目中,我从不参考错误消息中提到的DLL.那个dll出现在sql box上,但我无法将它添加到工作室,因为它在我尝试时会给出一些消息.我在这里尝试的东西已经用完了.这是90年代dll地狱了.

Mar*_*son 36

我在Windows Server 2012计算机上遇到了同样的问题.它在\ Windows\System32中有一个SqlServerSpatial110.dll文件,但没有SqlServerSpatial.dll.解决方案是在计算机上安装SQL Server 2008 R2的Microsoft System CLR类型.

  1. http://www.microsoft.com/en-us/download/details.aspx?id=26728
  2. 单击下载
  3. 根据您的处理器架构检查其中一个:

    • 1033\x64\SQLSysClrTypes.msi
    • 1033\x86\SQLSysClrTypes.msi
    • 1033\IA64\SQLSysClrTypes.msi
  4. 单击下一步

  • SQL 2012也安装了这个dll,SQL 2014没有!它安装SqlServerSpatial120.dll版本,但不能解决问题. (2认同)
  • 如果您在x64机器上运行x86进程,则需要获取1033\x86\SQLSysClrTypes.msi而不是x64版本. (2认同)

dav*_*ooh 26

我的问题与您的问题类似:我在远程Azure虚拟机上安装了我的ASP.NET MVC项目,我得到了以下异常:

"Unable to load DLL 'SqlServerSpatial110.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)" 
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我遵循了以下步骤:

  1. 我在项目中添加了对缺少的包的引用:

    PM> Install-Package Microsoft.SqlServer.Types
    
    Run Code Online (Sandbox Code Playgroud)
  2. 然后我强制将"复制到输出目录"选项强制为"复制始终" SqlServerSpatial110.dll(可能此步骤并非严格要求......)

  3. 对于ASP.NET项目,您需要将以下代码行添加到Application_Start方法中Global.asax.cs:

    SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~/bin"));
    
    Run Code Online (Sandbox Code Playgroud)

    最后一步对我来说很重要,因为在这行代码中没有Web应用程序加载DLL.

  • 按照你的指示,它运作良好.(步骤2没有必要) (3认同)
  • 我安装了`Microsoft.SqlServer.Types`包,但在我的项目中无法识别类型`SqlServerTypes`. (3认同)
  • AC#文件作为NuGet包内容的一部分添加到项目中,它包含`SqlServerTypes.Utilities`.NuGet还将运行一个安装脚本,将DLL复制到有用的位置,但如果您使用Paket作为包管理器,它不会运行安装脚本(作为一项功能),因此还有更多工作要做. (2认同)

Hos*_*Rad 7

我已经Microsoft.SqlServer.Types.dll在WPF和ASP.NET应用程序中使用SqlGeometry了多年的类型和空间查询(从第10节开始),这里是我发现成功加载的最新技巧,SqlServerSpatialXXX.dll作为其中的先决条件之一Microsoft.SqlServer.Types.dll.

  • SqlGeometrySqlGeography类型可以通过引用来在VS项目(例如C#)中使用Microsoft.SqlServer.Types.dll.
  • Microsoft.SqlServer.Types.dll是一个托管库,并有一些非托管库作为先决条件,它们就像SqlServerSpatialXXX.dllmsvcrXXX.dll
  • Microsoft.SqlServer.Types.dll但是,自从Sql Server 2008提供不同版本的版本以来,我从2012年开始看不到任何功能变化.

考虑64位/ 32位问题

  • 对于64位machanies,如果为Sql Server安装CLR类型,您可以在Windows/System32中找到这些先决条件文件的64位版本,还可以在Windows/SysWOW64文件夹中找到32位版本的先决条件文件
  • 如果机器上没有安装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");
}
Run Code Online (Sandbox Code Playgroud)

考虑不同项目类型中的二进制路径 建议在项目的执行路径中有一个名为SqlServerTypes的文件夹,如下所示

SqlServerTypes> 64

SqlServerTypes> X32

并加载这样的非托管程序集

Utilities.LoadNativeAssembliesv13(Environment.CurrentDirectory); //WPF
Utilities.LoadNativeAssembliesv13(HttpRuntime.BinDirectory); //ASP.NET 
Run Code Online (Sandbox Code Playgroud)

使用ADO.NET从Sql Server读取SqlGeometry时的问题 尽管Microsoft.SqlServer.Types.dll您使用的是哪个版本,如果您尝试使用ADO.NET从Sql Server读取它们,您可能会遇到强制转换异常,因为SQL Client默认情况下会加载版本10.0.0.0的Microsoft.SqlServer.Types.dll.在这种情况下,几年前我尝试了WKB(方法1和2)和WKT作为介质,在SqlGeometry不同版本的类型之间进行转换Microsoft.SqlServer.Types.dll,发现WKB快了大约10倍但是在一个月前我发现使用程序集重定向我们可以强制程序加载我们正在使用的版本并使用简单的演员我们可以得到SqlGeometry(方法3)

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;
}
Run Code Online (Sandbox Code Playgroud)