Any application that uses Entity Framework’s spatial data type support to target SQL Server requires the ‘CLR Types for SQL Server’ to be available on the machine the application runs on. This also applies to applications that use SQL Server spatial data types directly, without using Entity Framework.
任何应用程序如果使用空间数据类型,都需要SQL服务器安装在程序所发布的服务器上。但是也有一种方式可以直接使用空间数据类型而不需要安装SQL数据库。减少环境的依赖性。
在网上查找很多资料,都不能得到良好的解决。
问题是这样的,我的API服务使用了空间数据类型 DbGeography和DbGeometry ,本来发布在一个服务器上一切运行正常,后来发布到另一个服务器上之后,发现如下错误:
System.InvalidOperationException: DataReader.GetFieldType(5) returned null.
数据库中查看发现指定的字段位置为空间坐标类型,应该是发布之后,需要的程序集支持不在而导致的
经历的波折就不多说了,先把解决方案给出:
step1:NuGet package. 中安装SQL Server Spatial Types(#foo)
Microsoft.SqlServer.Types dependency. Includes the unmanaged dependency SqlServerSpatial.dll in the package 'tools' directory.
其中包含我们所需要的两个程序集:Microsoft.SqlServer.Types .dll 和 SqlServerSpatial.dll
下面是该安装包中,两个程序集的具体位置
下面的这个程序集是不可被引用的
Step2:引用程序集
将程序集Microsoft.SqlServer.Types .dll添加到项目应用中,并设置属性复制到本地为true
step3:修改web.config
一定要注意程序集的版本信息要与该配置文件设定一致
step4: 发布服务
会发现出现如下错误:
Message: UNKNOW_EXCEPTION
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.DllNotFoundException: Unable to load DLL 'SqlServerSpatial.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
at Microsoft.SqlServer.Types.GLNativeMethods.Length(GeoMarshalData g, Double& result)
at Microsoft.SqlServer.Types.GLNativeMethods.Length(GeoData g)
at Microsoft.SqlServer.Types.SqlGeometry.STLength()
--- End of inner exception stack trace ---
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__1.MoveNext()
找不到第二个程序集,这也无可厚非,毕竟没有添加到当前项目,发布的时候也不会有该程序集。因为这个程序集是不可添加的。
也没有找到很好的解决方案。