Why does the compiler think this is an Object instead of a DataRow?
Asked Answered
K

3

5

I'm using a LINQ query to translate data inside a DataTable object to be a simple IEnumerable of a custom POCO object.

My LINQ query is:

    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)
              }

However, the compiler is throwing a warning message under dr As DataRow with the message:

Option Strict On disallows implicit conversions from 'Object' to 'System.Data.DataRow'.

Why am I getting this error and what do I need to do to fix it? I would have thought that dtMessages.Rows returned a collection of type DataRow. Is this not correct?

Kean answered 2/8, 2010 at 14:40 Comment(5)
Show how dtMessages is declared and instantiated.Jameyjami
@Jameyjami I updated my post with more infoKean
Just turn off Option Strict! I kid, I kid.Olivette
@Olivette He should turn off VB.NET instead. :)Jameyjami
@Jameyjami Although I generally prefer C# to VB.NET, I get paid to write code in VB.NET, so it would be a very expensive decision to throw it away :-).Kean
S
13

Lok at DataTable.Rows - it's a DataRowCollection which only implements IEnumerable, not IEnumerable(Of DataRow).

Fortunately, there's an extension method in DataTableExtensions which lets you call AsEnumerable() instead of Rows; AsEnumerable returns an IEnumerable(Of DataRow):

Dim qry = From dr As DataRow In dtMessages.AsEnumerable()
          ...

(I prefer this over using dt.Rows.Cast(Of DataRow), as it gives less of an impression of something which might fail. It's more tailored to DataTable. Both will work though.)

Spanish answered 2/8, 2010 at 14:46 Comment(0)
O
8

The type System.DataTable predates generics in .Net and hence returns a plain old IEnumerable instead of an IEnumerable(Of DataRow) even though under the hood they are instances of DataRow. Hence the type of dr in the above query is Object and not DataRow.

You can work around this by using the Cast extension method to make the type of the collection explicit

From dr As DataRow in dtMessages.Rows.Cast(Of DataRow)
Oira answered 2/8, 2010 at 14:45 Comment(0)
L
3

The DataTable.Rows property returns a collection of DataRow, however that collection doesn't implement IEnumerable<DataRow> but IEnumerable, which works as IEnumerable<Object>.

You can explicitly cast the collection items to DataRow using dtMessages.Rows.Cast<DataRow>().

Lance answered 2/8, 2010 at 14:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.