如何在 ASP.NET Core 1.0 应用程序中使用 SqlServer.Types / 空间类型

Posted

技术标签:

【中文标题】如何在 ASP.NET Core 1.0 应用程序中使用 SqlServer.Types / 空间类型【英文标题】:How to use SqlServer.Types / spatial types within ASP.NET Core 1.0 application 【发布时间】:2016-12-18 22:15:03 【问题描述】:

我们的一个类库使用 Microsoft 空间类型,例如 DbGeography。在没有旧版本 SQL Server 和 Visual Studio 的干净机器上运行我们的应用程序时,我们会收到以下异常:

空间类型和功能不适用于此提供程序 因为程序集 'Microsoft.SqlServer.Types' 版本 10 找不到或更高。

解决方案显然是安装这个 nuget 包:

Install-Package Microsoft.SqlServer.Types

安装后,nuget 包会提供有关如何引用每个项目类型的 DLL 的说明:

要将使用空间数据类型的应用程序部署到未安装“SQL Server 的系统 CLR 类型”的计算机,您还需要部署本机程序集 SqlServerSpatial110.dll。

此程序集的 x86(32 位)和 x64(64 位)版本都已添加到您的项目中的 SqlServerTypes\x86 和 SqlServerTypes\x64 子目录下。如果未安装 C++ 运行时,还包括本机程序集 msvcr100.dll。

您需要添加代码以在运行时加载正确的这些程序集之一(取决于当前架构)。

ASP.NET 应用程序 对于 ASP.NET 应用程序,将以下代码行添加到 Global.asax.cs 中的 Application_Start 方法: SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~/bin"));

桌面应用程序 对于桌面应用程序,添加以下代码行以在执行任何空间操作之前运行: SqlServerTypes.Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory);

nuget 包项目站点没有响应,所以我不确定这是 2016 年现在使用的最佳方法。

我的问题是,我不知道如何从 ASP.NET Core 1.0 应用程序调用 LoadNativeAssemblies。 我们使用的是完整框架 (net461),而不是核心框架。

public class Startup

    public Startup(IHostingEnvironment env)
    
        ...
        SqlServerTypes.Utilities.LoadNativeAssemblies(env.WebRootPath);
        ...
    

在 ASP.NET 1.0 应用程序中包含 SqlServer.Types dll 文件的最佳方式是什么?

*** 上的相关问题 here 和 here。

非常感谢。

【问题讨论】:

你有什么收获吗? 没有任何进展。我仍然希望弄清楚... 出于好奇,如果不包括该行会怎样?在我的 .NET Framework 项目中,我不需要手动加载程序集,它运行良好。由于其他兼容性问题,我还没有设法在 .NET Core 上运行它。 这个问题解决了吗?如果没有,除了不使用 .net 核心,我们还能做些什么。 【参考方案1】:

我今天在一个 ASP.NET Core 应用程序上工作(下面是 .NET Framework,而不是 .NET Core,与原始海报相同)。

我注意到,将 Nuget 包直接添加到我的 ASP.NET Core 站点不会产生额外的文件。不确定这些包是否已更新为与 ASP.NET Core 一起使用?

无论如何,我只是将包添加到传统的 .NET Framework 4.x 项目中,并删除了它创建的 SqlServerTypes 文件夹,然后将该文件夹放在我的 ASP.NET Core 项目的根目录中。将下面所有 4 个 DLL 的 Copy to Output Dicrectory 属性从 Do not copy 更改为 Copy Always,并将调用添加到 LoadLibrary()

值得注意的是,14.x版本的包实际上是SQL vNext,并没有出来,在我的脑海里应该已经被标记为预发布了。我坚持使用 13.x,因为我们使用的是 SQL 2016。

最初我将它放在 Program.cs 文件中,因为它与中间件、ServiceInjection 或托管配置设置没有任何关系。但是你必须从反射中获得路径,这感觉很难看。所以我把它作为 Startup 构造函数的第一行,因为从那里我可以使用 HostingEnvironment 路径。

public Startup(IHostingEnvironment env)

    SqlServerTypes.Utilities.LoadNativeAssemblies(env.ContentRootPath);

    //The normal config as usual down here...
    var configuration = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.env.EnvironmentName.json", optional: true)
        .AddEnvironmentVariables();

【讨论】:

我已经尝试过了,甚至可以逐步检查 LoadNativeAssemblies 以确保它被调用,但在通过 EF 声明“Microsoft.SqlServer.Types”版本 10 或更高版本实际使用类型时,我仍然会遇到错误找不到。你还做了什么吗? 您可能还需要在LoadNativeAssemblies 调用之后添加SqlProviderServices.SqlServerTypesAssemblyName = typeof(SqlGeography).Assembly.FullName;。见***.com/a/40166192/1727 在我的情况下我没有这样做,但我没有使用实体框架,尽管我意识到原始问题被标记为 EF,尽管帖子从未真正提到它。我提到的步骤与 DAL 无关。这在 EF6 或 EF Core 中是否相关? Microsoft.SqlServer.Types 没有 Utilities 属性,是的,我使用的是最新的 Microsoft.SqlServer.Types nuget 包。我错过了什么? 它实际上不是程序集的一部分,它是一个简单的方法,Nuget 包在您第一次添加它时作为内容项添加到您的项目中。查找应该作为软件包安装过程的一部分添加的 Loader.cs 文件。【参考方案2】:

我用 web.config 文件中的 bindingRedirect 来解决这个问题。

  <dependentAssembly>
    <assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-14.0.0.0" newVersion="14.0.0.0" />
  </dependentAssembly>

我使用 SQL 2016、ASP.NET(无核心)和 EF 6.0.0.0

【讨论】:

这个问题是专门针对 ASP.NET Core 的,所以你的回答在任何方面都没有用。【参考方案3】:

这似乎对我有用:

    public class Startup
    
        public Startup(IHostingEnvironment env)
        
            ...
            SqlServerTypes.Utilities.LoadNativeAssemblies(env.WebRootPath + @"path to the project that contains the SQLServerTypes folder");
            ...
        
    

我注意到IHostingEnvironment.WebRootPath 返回指向 wwwroot 的路径,但是在我的解决方案设置中,我在该文件夹中有多个项目,所以只需告诉它指向哪个项目对我有帮助。抱歉,如果这没有帮助。

【讨论】:

在调试这对我有用SqlServerTypes.Utilities.LoadNativeAssemblies(HostingEnvironment.MapPath("~/bin"));【参考方案4】:

我修复了它,它不是一个干净的修复,实际上它是除了干净之外的一切:

我必须在 /bin 中使用 sql server types 包创建一个名为 packages 的文件夹...而且我必须在使用 sql server 类型的 asp net core 引用的每个项目中都这样做,所以它似乎是目标文件中的错误或错误行为。

请注意,此解决方法必须由团队中的每个人完成,因为 /bin 内容不会像预期的那样受源代码控制。

我希望它有所帮助(同时它已修复)

(好吧,太晚了,明天我会更多地考虑导致问题的原因以及我如何解决它,如果我找到更好的解决方法,我会告诉你,知道它会按预期构建和运行)

【讨论】:

【参考方案5】:

使用 .net 核心 2.0。在安装了上面提到的 nuget 包之后,我把它放在 Program.cs 之前的 BuildWebHost(args).Run();它奏效了..

Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory); SqlProviderServices.SqlServerTypesAssemblyName = "Microsoft.SqlServer.Types, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91";

【讨论】:

【参考方案6】:

对 bin 目录的引用对我有用 :)

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

【讨论】:

以上是关于如何在 ASP.NET Core 1.0 应用程序中使用 SqlServer.Types / 空间类型的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core 1.0 应用程序中使用 SqlServer.Types / 空间类型

如何在 asp.net core 1.0 中查看当前 url

ASP.NET Core 1.0 的 Kudu 部署脚本

.NET Core 1.0ASP.NET Core 1.0和EF Core 1.0简介

ASP.NET Core 1.0 基础与应用启动

如何在 ASP.NET Core 1.0 的 DI 中的 Startup 类中添加 IHttpContextAccessor?