为什么编译器认为这是一个Object而不是DataRow?

Ben*_*ack 4 .net linq vb.net casting option-strict

我正在使用LINQ查询将DataTable对象内的数据转换IEnumerable为自定义POCO对象的简单.

我的LINQ查询是:

    Dim dtMessages As DataTable

    '...dtMessages is instantiated ByRef in a helper data access routine... '

    Dim qry = From dr As DataRow In dtMessages.Rows
              Select New OutboxMsg With {
                  .ComputerID = dr(dcComputerID),
                  .MessageData = dr(dcMessageData),
                  .OutBoxID = dr(dcOutBoxID),
                  .OutBoxReceivedID = dr(dcOutBoxReceivedID),
                  .TrxDate = dr(dcTrxDate)
              }
Run Code Online (Sandbox Code Playgroud)

但是,编译器会在消息下面发出警告dr As DataRow消息:

Option Strict On禁止从"Object"到"System.Data.DataRow"的隐式转换.

为什么我会收到此错误,我需要做些什么才能修复它?我原本以为它dtMessages.Rows返回了一个类型的集合DataRow.这不正确吗?

Jon*_*eet 12

DataTable.Rows- 这是一个DataRowCollection只实现IEnumerable,而不是IEnumerable(Of DataRow).

幸运的是,有一种扩展方法DataTableExtensions可以让你调用AsEnumerable()而不是Rows; AsEnumerable返回一个IEnumerable(Of DataRow):

Dim qry = From dr As DataRow In dtMessages.AsEnumerable()
          ...
Run Code Online (Sandbox Code Playgroud)

(我更喜欢使用dt.Rows.Cast(Of DataRow)它,因为它给人的印象很少,可能会失败.它更适合DataTable.两者都可以工作.)


Jar*_*Par 8

该类型System.DataTable早于.Net中的泛型,因此返回一个普通的旧IEnumerable而不是一个IEnumerable(Of DataRow)即使虽然在它们的实例之下DataRow.因此类型dr在上面的查询是Object而不是DataRow.

您可以使用Cast扩展方法解决此问题,以使集合的类型显式

From dr As DataRow in dtMessages.Rows.Cast(Of DataRow)
Run Code Online (Sandbox Code Playgroud)