33

我正在尝试在 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 框中,但我无法将其添加到工作室,因为当我尝试添加时它会给出一些消息。我没有东西可以在这里尝试了。又是 90 年代的 dll 地狱。

4

10 回答 10

36

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

  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. 单击下一步

于 2013-02-10T11:01:40.940 回答
29

我的问题与您的问题相似:我在远程 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. 然后我将“复制到输出目录”选项强制为“始终复制” SqlServerSpatial110.dll可能这一步不是严格要求的......

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

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

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

于 2016-01-19T11:55:21.583 回答
8

多年来,我一直Microsoft.SqlServer.Types.dll在 WPF 和 ASP.NET 应用程序中使用SqlGeometry类型和空间查询(自 v.10 起),这里是我发现成功SqlServerSpatialXXX.dll加载Microsoft.SqlServer.Types.dll.

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

考虑 64bit/32bit 问题

  • 对于 64 位机器,如果您安装 CLR Types for Sql Server,您可以在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");
}

考虑不同项目类型中的二进制路径建议在你的项目的执行路径中 有一个名为SqlServerTypes的文件夹,像这样

SqlServerTypes>x64

SqlServerTypes>x32

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

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

使用 ADO.NET 从 Sql Server 读取 SqlGeometry 时的问题 尽管您使用的是哪个版本,Microsoft.SqlServer.Types.dll但如果您尝试使用 ADO.NET 从 Sql Server 读取它们,您可能会遇到强制转换异常,因为 SQL 客户端默认加载版本 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;
}
于 2016-11-30T05:09:26.250 回答
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

我在下面放了说明:

  1. 打开 Visual Studio 并打开 NuGet 包管理器
  2. 搜索“Microsoft.SqlServer.Types”
  3. 安装...

该软件包会将必要的 .DLL 安装到您的解决方案/项目中。它还会将一些额外的库直接复制到您的 /bin 目录中。您必须在 global.asax.cs/vb 文件中连接对这些附加库的引用。NuGet 包中包含有关如何执行此操作的说明。下面是 NuGet 包的直接链接(希望 MSFT 也不会忘记它)。

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

于 2014-08-28T17:57:35.083 回答
4

尽管安装了 SQL Server 14.x,VS 仍然坚持找不到SqlServerSpatial 110 .dll。

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

因此,我安装了Microsoft.SqlServer.Types14.x,然后在 /x86 和 /x64 文件夹中将 SqlServerSpatial 140 .dll 文件重命名为 SqlServerSpatial 110 .dll 并在Loader.cs. 无论出于何种原因,这似乎起到了作用。

于 2018-03-11T06:10:37.000 回答
2

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

I Resolved it by Updating my EF5 to EF6

在包管理器控制台中运行到 EF5 到 EF 最新

Install-Package EntityFramework 
于 2017-12-16T17:55:15.693 回答
1

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

于 2017-06-17T03:17:50.957 回答
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";

希望这可以帮助某人。

于 2019-03-19T14:26:10.867 回答
0

这是对我造成此问题的原因:-

我的项目中有一个名为的文件夹SQLServerTypes,当我查看该文件夹时,我发现 .dll 实际上丢失了。因此,下载 .dll 并将其粘贴到SQLServerTypes文件夹中为我解决了这个问题。

当我尝试构建我的应用程序时,这个问题就发生在我身上。

于 2020-03-09T16:07:35.857 回答
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

于 2019-06-21T18:44:38.640 回答