[Solved] How to resolve InvalidCastException after translating LINQ-to-JSON query from c# to VB.NET?


In order for {columns}.Concat(rows) to work, it seems you need to add an explicit call to AsEnumerable() in order to make sure the type TSource for Enumerable.Concat(IEnumerable<TSource>, IEnumerable<TSource>) is inferred correctly:

Dim csvRows = { columns.AsEnumerable() }.Concat(rows) _
                .Select(Function(r) String.Join(",", r))

Fixed fiddle #1 here.

A DirectCast({columns}, IEnumerable(Of IEnumerable(Of String))) also seems to work, as mentioned in comments by Ahmed Abdelhameed:

Dim csvRows = DirectCast({columns}, IEnumerable(Of IEnumerable(Of String))).Concat(rows) _
                .Select(Function(r) String.Join(",", r))

Fixed fiddle #2 here.

Calling Enumerable.Concat(Of IEnumerable(Of String)) explicitly, without making use of inferencing, works also:

Dim csvRows = Enumerable.Concat(Of IEnumerable(Of String))({columns}, rows) _
                .Select(Function(r) String.Join(",", r))

Fixed fiddle #3 here.

Thus your entire code should look like:

Dim obj As JObject = JObject.Parse(json)

Dim values = obj.DescendantsAndSelf().OfType(Of JProperty)().Where(Function(p) TypeOf p.Value Is JValue).GroupBy(Function(p) p.Name).ToList()
Dim columns = values.[Select](Function(g) g.Key).ToArray()

Dim parentsWithChildren = values.SelectMany(Function(g) g).SelectMany(Function(v) v.AncestorsAndSelf().OfType(Of JObject)().Skip(1)).ToHashSet()

Dim rows = obj.DescendantsAndSelf() _
                    .OfType(Of JObject)() _
                    .Where(Function(o) o.PropertyValues().OfType(Of JValue)().Any()) _
                    .Where(Function(o) o.Equals(obj) OrElse Not parentsWithChildren.Contains(o)) _
                    .Select(Function(o) columns.Select(Function(c) _
                                                    o.AncestorsAndSelf() _
                                                    .OfType(Of JObject)() _
                                                    .Select(Function(parent) parent(c)) _
                                                    .OfType(Of JValue)() _
                                                    .Select(Function(v) CStr(v)) _
                                                    .FirstOrDefault()) _
                                                .Reverse() _
                                                .SkipWhile(Function(s) s Is Nothing) _
                                                .Reverse())

Dim csvRows =  { columns.AsEnumerable() }.Concat(rows) _
                .Select(Function(r) String.Join(",", r)) 
Dim csv = String.Join(vbLf, csvRows)        

solved How to resolve InvalidCastException after translating LINQ-to-JSON query from c# to VB.NET?