在 ASP.Net 中使用 SQL Server 2012 地理数据类型 - DataReader.GetFieldType(x) 返回 null

Posted

技术标签:

【中文标题】在 ASP.Net 中使用 SQL Server 2012 地理数据类型 - DataReader.GetFieldType(x) 返回 null【英文标题】:Using SQL Server 2012 Geography Data Type with ASP.Net - DataReader.GetFieldType(x) returned null 【发布时间】:2014-08-26 12:15:14 【问题描述】:

我编写了一个运行良好的 ASP.Net 4 应用程序。但是,我决定使用 Sql Sever 2012 中的新地理数据类型。这在我的本地计算机上运行良好,但在我上传时失败。

出现错误“DataReader.GetFieldType(9) 返回 null。”在对包含这些数据类型之一的表执行通常的“select * FROM Table”查询时。

我已经搜索了有关在我的项目中添加对 Microsoft.SqlServer.Types.dll 的引用并将 Copy Local 更改为 true 的各种线程。但是我遇到了同样的错误。

我在两个单独的服务器上运行数据库和 Web 服务器,所以我认为 Web 服务器上没有任何程序集,除非我将它们与我的项目一起上传。

我是否缺少任何其他需要的程序集?或任何其他设置?

我花了几天时间尝试解决这个问题并上传各种库。任何帮助将不胜感激。

【问题讨论】:

服务器上数据库的兼容级别是多少? 【参考方案1】:

msdn

当 SQL Server 2012 中的兼容级别为 100 或更低时,地理数据类型具有以下限制:

•每个地理实例必须适合单个半球。不能存储大于半球的空间对象。

•来自开放地理空间联盟 (OGC) 知名文本 (WKT) 或知名二进制 (WKB) 表示的任何地理实例如果生成大于半球的对象,就会引发 ArgumentException。

•需要输入两个地理实例的地理数据类型方法,例如 STIntersection()、STUnion()、STDifference() 和 STSymDifference(),如果方法的结果不适合其中,则将返回 null一个半球。如果输出超过单个半球,STBuffer() 也将返回 null。

【讨论】:

我实际上在列中还没有任何数据,所以无论如何该值都是空的。但是它返回了一个 ASP.Net 错误,因为它似乎无法填充 DataSet。但是我将数据库的兼容性级别提升到 110 仍然有同样的错误??【参考方案2】:

据我所知,当您最初添加引用时,至少需要在本地安装 SQL Server。如果可以的话,我会先尝试在本地安装 SQL Express(您不需要使用它,只需安装它),然后再次尝试您的代码,看看是否是问题所在。

参考资料:

DataReader.GetFieldType returned null

http://blogs.bing.com/maps/2013/08/05/advance-spatial-queries-using-entity-framework-5/

编辑:

我更熟悉通过实体框架使用空间类型。如果您想直接使用它们,您似乎需要使用 nuget 包才能将所需的 DLL 放入项目中。来自 Microsoft ADO.NET 博客页面

SqlServerSpatial110.dll – 这是一个本机程序集,因此不能作为项目引用添加。

参考资料:

微软 ADO.NET 博客

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

相关的 SO 问题

'Microsoft.SqlServer.Types' version 10 or higher could not be found on Azure https://gis.stackexchange.com/questions/382/how-can-i-use-sql-servers-spatial-types-from-a-net-application

【讨论】:

谢谢。然而,这正是我所做的。我在本地安装了 SQL Server 2012,并使用程序集 -> 扩展 -> Microsoft Sql Server 类型添加了引用。但仍然没有快乐 您在另一台服务器上运行的是什么版本的 SQL。只是想确保本地 SQL 2012 DLL 与您的服务器地理数据类型不冲突。正如 Martin Smellworse 在他的回答中所说,版本之间的类型有很多变化,如果它们不同,它可能不起作用。 服务器正在运行 11.0.3000.0(Microsoft SQL Server Express(64 位))。本地版本为 11.0.3128.0 (Microsoft SQL Server Express (64-bit)).. 所以,我尝试从数据库服务器中提取 Microsoft.SqlServer.Types.dll 并将其添加到我的 bin 文件夹中。然后引用它。然而仍然没有喜悦。它在本地工作,但不在服务器上。 您是否在本地和服务器上使用相同的实体框架版本以及实体框架 5 不支持空间类型仅在 .NET 4 .NET 4.5 上来源:msdn.microsoft.com/en-us/data/dn194325.aspx【参考方案3】:

为此花费了大量时间,还添加了引用,但我找到了一个我想分享的解决方法。 在 asp.net 上也应该可以正常工作。

我使用以下查询来解析对象的字符串表示形式:

DECLARE @result geography;
SELECT @result = area FROM news WHERE id LIKE @id ;
SELECT ...,  @result.STAsText() as area FROM news WHERE id LIKE @id;

在 asmx (c#) 网络服务中,我使用解析器方法检索了我的 SQLGeography:

row["area"].ToString()

之后,您可以使用解析器方法来检索 SQLGeography 对象。

/// <summary>
/// Converts a String into an sql geography object.</summary>
/// <param name="pText">The string representation of the sql geography object. </param>
public static SqlGeography GetGeographyFromText(String pText)

    SqlString ss = new SqlString(pText);
    SqlChars sc = new SqlChars(ss);
    try
    
        if (pText.Contains("POINT"))
        
            return SqlGeography.STPointFromText(sc, 4326);
        
        return SqlGeography.STPolyFromText(sc, 4326);
    
    catch (Exception ex)
    
        return SqlGeography.STMPolyFromText(sc, 4326);
        throw ex;
    

希望对大家有所帮助!

【讨论】:

【参考方案4】:

最后我无法让它像在我的开发机器上那样工作,我不想在 Web 服务器上安装 Visual Studio 或 SQL Server Express,所以我只是删除了我所做的所有查询“SELECT * FROM Table”并且错误消失了。它仍然让我使用地理字段进行计算,但不喜欢你试图在屏幕上显示它。感谢您的所有帮助!

【讨论】:

以上是关于在 ASP.Net 中使用 SQL Server 2012 地理数据类型 - DataReader.GetFieldType(x) 返回 null的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 使用 2 个表(外键?) ASP.NET

如何在 SQL Server 表中创建图像列并使用 VB 在 ASP.NET 中检索它

无法在 Visual Studio 2012 的 asp.net 中使用 sql server ce 4.0

JavaScript、asp.net 和 Sql Server

如何通过 C# ASP.net 从 SQL Server 中的文本框中存储日期

使用 C# 在 ASP.NET 中检查 SQL Server 表中的列值是不是为空