无法加载SqlServerSpatial.dll

时间:2013-01-10 19:34:56

标签: c# .net 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地狱了。

10 个答案:

答案 0 :(得分:35)

我在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 \的 64 \ SQLSysClrTypes.msi
    • 1033 \的 86 \ SQLSysClrTypes.msi
    • 1033 \ IA64 \ SQLSysClrTypes.msi
  4. 点击下一步

答案 1 :(得分:25)

我的问题与您的问题类似:我在远程Azure虚拟机上安装了我的ASP.NET MVC项目,但我得到了这个例外:

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

要解决这个问题,我按照以下步骤操作:

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

    PM> Install-Package Microsoft.SqlServer.Types
    
  2. 然后我强制将#34;复制到输出目录"选项"始终复制"对于SqlServerSpatial110.dll可能此步骤并非严格要求......

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

    SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~/bin"));
    

    这个最后一步对我来说是基本的,因为在这行代码中没有Web应用程序加载DLL。

答案 2 :(得分:7)

我一直在WPF和ASP.NET应用中使用Microsoft.SqlServer.Types.dll来处理SqlGeometry类型和空间查询多年(从第10版开始),这是我发现成功加载的最新提示 SqlServerSpatialXXX.dll Microsoft.SqlServer.Types.dll的先决条件之一。

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

考虑64位/ 32位问题

  • 对于64位machanies,如果为Sql Server安装CLR类型,您可以在 Windows / System32 中找到这些先决条件文件的64位版本,还可以在 Windows / SysWOW64 文件夹
  • 如果计算机上未安装CLR类型,则应根据项目(32位或64位)手动加载这些先决条件的正确版本(32位/ 64位),否则会出现错误,如
  

加载SqlServerSpatialXXX.dll时出错

您可以使用Environment.Is64BitProcess在C#中运行时检查32位/ 64位问题。以下是示例代码:

[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> 64

SqlServerTypes> X32

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

Utilities.LoadNativeAssembliesv13(Environment.CurrentDirectory); //WPF
Utilities.LoadNativeAssembliesv13(HttpRuntime.BinDirectory); //ASP.NET 

使用ADO.NET从Sql Server读取SqlGeometry时的问题 尽管您正在使用哪个版本的Microsoft.SqlServer.Types.dll,但如果您尝试read them from Sql Server using ADO.NET,则可能会遇到强制转换异常,因为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;
}

答案 3 :(得分:4)

我在Windows Server 2008 R2计算机(Azure VM)上遇到问题,但上述步骤均无法解决问题。我安装了CLR类型。我把文件放在我的Web应用程序的BIN文件夹中。依然没有。我终于在微软的人那里看到了这个博客并且它起了作用。我在这里留下网址,以防它可以帮助其他任何人。

http://blogs.msdn.com/b/adonet/archive/2013/12/09/microsoft-sqlserver-types-nuget-package-spatial-on-azure.aspx

由于上述链接不再有效(感谢MSFT!),我已在下面说明:

  1. 打开Visual Studio并打开NuGet包管理器
  2. 搜索&#34; Microsoft.SqlServer.Types&#34;
  3. 安装...
  4. 此软件包将在您的解决方案/项目中安装必要的.DLL。它还会将一些其他库直接复制到您的/ bin目录中。您必须在global.asax.cs / vb文件中连接对这些附加库的引用。 NuGet包中包含有关如何执行此操作的说明。下面是NuGet包的直接链接(希望MSFT也不会忘记这一点)。

    https://www.nuget.org/packages/Microsoft.SqlServer.Types/

答案 4 :(得分:3)

尽管安装了SQL Server 14.x,但VS仍坚持使用SqlServerSpatial 110 。未找到.dll。

安装 SQL Server 2008 R2的Microsoft系统CLR类型没有修复它。我还尝试安装10.5版本的Microsoft.SqlServer.Types,但收到了关于方法签名不匹配的PInvoke错误。

相反,我安装了Microsoft.SqlServer.Types 14.x,然后在/ x86和/ /中将SqlServerSpatial 140 .dll文件重命名为SqlServerSpatial 110 .dll x64文件夹并在Loader.cs中执行相同操作。无论出于何种原因,这似乎都可以解决问题。

答案 5 :(得分:2)

我在使用Windows Server 2012 r2的godaddy VPS中遇到了同样的问题

I Resolved it by Updating my EF5 to EF6
包管理器控制台中的

运行到EF5到EF lalest

Install-Package EntityFramework 

答案 6 :(得分:1)

从References中删除Microsoft.SqlServer.Types.dll并使用Nuget进行安装。安装前检查您的版本。 x86和x64的程序集将安装在项目中。

答案 7 :(得分:0)

我在ASP.NET MVC 5项目中遇到了类似的问题。前阵子,我不得不添加一行以指定程序集名称,如下所示:

SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~/bin"));
SqlProviderServices.SqlServerTypesAssemblyName = Assembly.GetAssembly(typeof(Microsoft.SqlServer.Types.SqlGeography)).FullName;

我最近部署到了新的测试服务器,并再次遇到此错误。由于某种原因,它试图加载版本12。现在,我指定所需的确切版本,它可以按预期工作。

SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~/bin"));
SqlProviderServices.SqlServerTypesAssemblyName = "Microsoft.SqlServer.Types, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91";

希望这对某人有帮助。

答案 8 :(得分:0)

我有一个旧的(2009)asp.net webform vb.net项目,在另一个服务器上出现此错误。我必须将此运行时添加到web.config中:

<configuration>
  <runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" />
        <bindingRedirect oldVersion="1.0.0.0-11.0.0.0" newVersion="10.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

http://biandintegration.blogspot.com/2017/12/solved-unable-to-load-dll.html

答案 9 :(得分:0)

这是引起我此问题的原因:-

项目中有一个名为return DoubleStream.of(x, y, z, a, c).min().orElse(-1); 的文件夹,当我查看该文件夹时,我发现.dll实际上丢失了。因此,下载.dll并将其粘贴到SQLServerTypes文件夹中可以为我解决此问题。

当我尝试构建我的应用程序时,问题正在发生。