如何在 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
.NET Core 1.0ASP.NET Core 1.0和EF Core 1.0简介
如何在 ASP.NET Core 1.0 的 DI 中的 Startup 类中添加 IHttpContextAccessor?