简体   繁体   中英

Converting Linq to XML query from C# to VB.Net. Can you spot my error?

I'm converting the Linq query below from C# to VB.Net. Can you spot my error? The query joins 3 XML datasets. Thanks in advance!

C# - This one works great.

List<Course> courses =
  (from course in CourseXML.Descendants(ns + "row")
  join coursecategory in CourseCategoryXML.Descendants("Table") on (string)course.Attribute("code") equals (string)coursecategory.Element("DATA")
  join category in CategoryXML.Descendants("Table") on (string)coursecategory.Element("GRP") equals (string)category.Element("GRP")
  where (string)coursecategory.Element("RECTYPE") == "C"
  select new Course {
    CategoryCode = category.Element("GRP").Value,
      Code = course.Attribute("code").Value
  }).ToList<Course>();

VB - I'm getting no results from this, so I suspect I'm either casting improperly or joining improperly.

Dim result = (From course In CourseXML.Descendants(ns + "row") _
Join coursecategory In CourseCategoryXML.Descendants("Table") On CType(course.Attribute("code"), String) Equals CType(coursecategory.Element("DATA"), String) _
Join category In CategoryXML.Descendants("Table") On CType(coursecategory.Element("GRP"), String) Equals CType(category.Element("GRP"), String) _
Where CType(coursecategory.Element("RECTYPE"), String) = "C" _
Select New Course() With _ 
{ _
  .CategoryCode = category.Element("GRP").Value, _
  .Code = course.Attribute("code").Value _
}).ToList()

I used the following site to convert: http://www.developerfusion.com/tools/convert/csharp-to-vb/

Dim courses As List(Of Course) = (From course In CourseXML.Descendants(ns & "row") _
    Join coursecategory In CourseCategoryXML.Descendants("Table") On DirectCast(course.Attribute("code"), String) = DirectCast(coursecategory.Element("DATA"), String) _
    Join category In CategoryXML.Descendants("Table") On DirectCast(coursecategory.Element("GRP"), String) = DirectCast(category.Element("GRP"), String) _
    Where DirectCast(coursecategory.Element("RECTYPE"), String) = "C" _
    Select New Course()).ToList(Of Course)()

The main difference is the last Select.

You are getting different results because of the casts.

coursecategory.Element("RECTYPE").Value returns a different result than
(string)coursecategory.Element("RECTYPE") == "C" (and obviously CType(coursecategory.Element("RECTYPE"), String) = "C").

If one of your elements is missing a child RECTYPE node, you will not have any results if you properly cast it, which you did in VB.NET.

In C# you didn't cast (string)coursecategory.Element("RECTYPE") == "C" right. If you use ToString() or .Value you would get the correct results.

Use coursecategory.Element("RECTYPE").Value instead, and avoid the casts altogether.

You could test this by changing your select to return:

select new { 
Wrong = (string)coursecategory.Element("RECTYPE"),  // No exception ... incorrect result!
//Maybe = coursecategory.Element("RECTYPE").ToString() //throws NullReferenceException
//Right = (string)coursecategory.Element("RECTYPE").Value // throws NullReferenceException because of a missing element.
CategoryCode = category.Element("GRP").Value,      
Code = course.Attribute("code").Value

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM