DataReader.GetFieldType返回了空值

26

在我的数据库表Layout中,有一列类型为hierarchyid(列索引= 4)。

当我尝试设置新环境(从XEN服务器创建的虚拟Web服务器),然后运行网站时,我遇到了这个问题:

异常信息:DataReader.GetFieldType(4)返回null。 异常数据:System.Collections.ListDictionaryInternal

我进行了一些搜索,并发现已经有一些相关主题(例如在MSDN上)。

但即使我添加了C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Types.dll库,似乎结构中的db类型SqlHierarchyId仍未被识别。

仍会抛出"DataReader.GetFieldType(4)返回null"的异常。

注意:如果我在环境(Windows Server 2008 RC2)上安装VS2010中的C#包,则可以解决此问题,但我的老板不接受,因为这只是一个简单的Web服务器。

7个回答

28

从项目中引用Microsoft.SQLServer.Types dll,并将其设置为引用属性中的"Copy Local"。这样,在部署网站时,该DLL将与网站一起打包。然后,您就不需要在Web服务器上安装全部SQL Server才能使用SQL Server数据类型。我之所以这样做是因为我的网站正在使用geography数据类型列,而我遇到了相同的错误。


谢谢。这就是我已经做过的方式:我已经将 SQL Server 中的 Microsoft.SQLServer.Types.dll 库添加到我的解决方案的引用部分中。 - Undefined Identity
1
未来的搜索者们 - Nuget 中的 Microsoft.SQLServer.Types 版本为 v11,无法使用。请参考 OP 的帖子获取 DLL 路径;按照此处所示手动将其添加到您的项目中;然后您就可以使用 GetFieldType 并返回 Microsoft.SqlServer.Types.SqlHierarchyId 了。 - Mendhak
2
这是解决问题的“正确”方式吗?SQL Server 中有一个新的数据类型,然后我必须使用“复制本地”吗? - Anders Lindén

21

我尝试通过将Microsoft.SqlServer.Types NuGet包添加到我的项目中来解决这个问题,但仅仅这样做并不能解决问题。我还需要在我的项目的App.config文件的<assemblyBinding>元素中添加以下内容:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  .
  .
  .
    <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>
  .
  .
  .
  </assemblyBinding>
</runtime>

大赞!!!干得好@bgh,我在那个问题上想了好一会儿。 - Ebikeneser
这是最佳解决方案,因为它不依赖于本地dlls的安装。 - Dušan Knežević

12

对我有效的解决方案是在连接字符串中添加“Type System Version=SQL Server 2012”。

示例: string connectionString = “Data Source=myserver;Initial Catalog=mydatabase;User ID=sa;Password=*******;Type System Version=SQL Server 2012;”;


1
救了我的一天!谢谢!在将旧应用程序迁移到使用较新的SQL服务器的新服务器后,我遇到了这个问题。将此添加到连接字符串中将使其回退到这些旧的SQL服务器类型。(您可以通过Microsoft的Web平台安装程序下载它们)。 - Joel Harkes
1
这是一个非常好的答案!我正在使用SqlConnectionStringBuilder,并将Property TypeSystemVersion设置为“SQL Server 2012” - 我能够检索AdventureWorks2017的表模式信息,以及另一个我包含的数据库 - 尝试在单个模式中涵盖两个数据库,这消除了我的最后一个障碍。我点赞你的答案,因为它似乎是最不侵入性和最正确的解决此问题的方法。谢谢! - jinzai
不知道为什么,但这也拯救了我的一天! - uqji

1

如果其他解决方案仍然存在错误,请尝试在web.config文件中删除相关内容。

<add assembly="Microsoft.SqlServer.Types, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>

将文件Microsoft.SqlServer.Types.dll复制到bin文件夹中(或/和添加引用)
或在sqlconnectionstring中添加“Type System Version = SQL Server 2012;”

1
相对于更改您的项目并添加对 Microsoft.SQLServer.Types dll 的引用,您可以将其直接放入 GAC 中。
在我的情况下,我在开发机上有三个版本,并将它们添加到服务器 GAC 中。
 gacutil.exe -i .\10.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.Types.dll
 gacutil.exe -i .\11.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.Types.dll
 gacutil.exe -i .\12.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.Types.dll

我在服务器上安装了其他与SQL相关的第三方.NET工具,它们都遇到了同样的错误。将这些程序集添加到全局程序集缓存后,它们都可以正常工作。
虽然我不会将自己的程序集放入全局程序集缓存,但我认为将一些Microsoft SQL-Server程序集放在那里是可以的,因为它们会影响多个应用程序。

0
对于那些在PowerShell中遇到此问题的人,我能够通过安装Microsoft SQL Server 2016的SQLSysClrTypes.msi并重新启动PowerShell来解决我的问题。下载页面很难浏览,点击“下载”并搜索SQLSysClrTypes。选择正确的架构。
Exception calling "Fill" with "1" argument(s): "DataReader.GetFieldType(24) 
returned null."
At MyScript.ps1:15 char:5
+     $adapter.Fill($ds) | Out-Null
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], 
ParentContainsErrorRecordException
    + FullyQualifiedErrorId : InvalidOperationException

在我的情况下,有问题的数据类型是位于位置(24)的Microsoft.SqlServer.Types.SqlGeography。这个字段在安装了SQL Server 2016的AppVeyor中工作正常,但在我的本地环境中无法运行。
我找到了几篇文章解释了为什么会发生这种情况,并且有些指定使用NuGet获取最新版本的Microsoft.SqlServer.Types.dll,但在我的情况下,这并没有帮助,也没有尝试用Install-Package和其他工具替换assembly\GAC_...版本的成功。 注意:安装.msi并不像人们期望的那样直截了当,因为在尝试和错误的过程中,我安装了几个较旧的“Microsoft SQL Server System CLR Types”。 这导致MSI仅提供“修复”和“删除”选项。如果出现这种情况,请选择“删除”,然后再次运行安装程序。

安装正确的版本并重新启动PowerShell解决了问题。


0

对我来说,必须在其中添加10.0.0.0__89845dcd8080cc91文件夹

Microsoft.SqlServer.Types.dll

适用于版本10

到 C:\Windows\assembly\GAC_MSIL\Microsoft.SqlServer.Types

可能存在隐藏的依赖关系,使用 GAC 而不是项目目录。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接