0

I have a method that is passed in an EnumerableRowCollection(Of System.Data.DataRow),i want to be able to use the underlying datatable. Ultimately i want to be able to use the columns collection of that datatable.

currently i use

Dim t As System.Data.DataTable = TryCast(x(0), DataRow).Table

where x is EnumerableRowCollection(Of System.Data.DataRow)

This works fine, EXCEPT for the case where the count of rows is zero.

I am convinced that the underlying datatable definition is still there as i am able to access it through the debugger if i 'add watch' against x

in the watch window i see

x|{System.Data.EnumerableRowCollection(of System.Data.DataRow)}
System.Data.EnumerableRowCollection(of System.Data.DataRow)|{System.Data.EnumerableRowCollection(of System.Data.DataRow)}
ElementType| {Name="DataRow" FullName = "System.Data.DataRow"}
EnumerableRows|In-Memory Query
Table|{mydatatable}

It is mydatatable that i am after

if i try x.Table then i get

'table' is not a member of 'System.Collections.Generic.IEnumerable(Of System.Data.DataRow)'.

in my case the enumerablerowcollection is most likely being created from a datatable using LINQ with an orderby

 Dim z = (From d In mydataset.mydatatable.OrderBy(Function(c) c.myfield))

In summary, i want to be able to access the datatable from an EnumerableRowCollection(Of System.Data.DataRow) even if the count of EnumerableRows is zero. If this is not possible then please could you help me explain how teh watch window can display this. Am i allowed to add an image of what i am seeing in the watch window? I have added the image of what the debugger shows, how does it get this table info enter image description here

thehill
  • 93
  • 11
  • I don't have enough code here to test ideas, but what about just "faking it" by calling AddRow on the empty collection and reflecting that new row for your columns? – Nikki9696 Nov 30 '15 at 22:32
  • i will edit this tomorrow with a more useful code sample. i am having a little explore along the lines of your idea, i will update if that gets me anywhere – thehill Nov 30 '15 at 22:55
  • No, you cannot get info on the table from a zero-size collection. You would have to pass the table through another parameter. – Steve Nov 30 '15 at 23:19
  • Why do you want the underlying `DataTable`? Can you not take in a `DataTable` instead of the row collection? – D Stanley Nov 30 '15 at 23:52

1 Answers1

0

There is not a public property or method that exposes the underlying DataTable. The Table property you see in an internal property that is not publicly accessible. You could dig into this implementation detail using reflection:

var pi = rows.GetType().GetProperty("Table",BindingFlags.NonPublic | BindingFlags.Instance);
DataTable dt = pi.GetValue(rows) as DataTable;

But (hopefully obviously) these internal implementation details are brittle and subject to change.

Since the class itself is not intended to be used directly from your class, I would strongly suggest changing your approach to take in a DataTable as a parameter instead of this implementation-specific class.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • thanks, i have changed it to pass in the datatable as a parameter. I hadn't realized that EnumerableRowCollection was off-limits. I will use it for the short-term whilst i look for a better solution – thehill Dec 01 '15 at 10:34
  • @thehill Yes it's unfortunate that the return type for the `AsEnumerable` extension method returns a specific class instead of an `IEnumerable`. That way they could change the actual implementation type without breaking existing code. – D Stanley Dec 01 '15 at 14:47