Question

Edited to answer my own question. This appears to be a LINQ/VB bug.

A simple LINQ query returning an anomymous type will sometimes change the field names specified in the query so as to capitalize them. Perhaps passing the result of the query as a parameter to a method call:

someThing.someMethod(From someStuff In stuffList _
                     Select text = someStuff.Name(), _
                            value = someStuff.Id
                     )

where someMethod has signature

Public Sub someMethod(ByVal list As IEnumerable(Of Object))

If you step into the execution of someMethod, and then examine the value of list in quickwatch, you may or see the field names as "text"&"value" or "Text"&"Value".

LINQ queries should not be changing the field names as specified in the query, so the correct behavior is fieldnames "text"&"value". Yet production builds of our application have the incorrect capitalization behavior (which can be determined indirectly), and debug builds have shown it both happening both ways at different times and/or for different developers' machines.

I've looked high & low for some feature of LINQ which controls this behavior, but now am virtually certain it is a bug. (msdn forum thread, MS Connect bug page)

This is likely to only cause a problem if you are using reflection, such as type.getfield() such as in

listItem = list.ElementAt(index)
itemTextField = listItem.GetType().GetField("text")
itemText = CType(itemTextField.GetValue(listItem),String)

If this happens to you, the workaround is to use overload of GetField with bindingflags to make it case-insensitive:

itemTextField = listItem.GetType().GetField("text", BindingFlags.IgnoreCase)

It must be pretty rare to encounter this bug, but maybe the next person will spend less time scratching their head if they find this info here.

=========original post=========== Getting different behavior in my debug build environment than in my coworkers' and our production envirnonment, relating to LINQ and reflection...

While running debug build of legacy code, the following code

    Dim objectType As Type = obj.GetType()
    Dim field As FieldInfo = objectType.GetField(name)
    Dim prop As PropertyInfo = objectType.GetProperty(name)

results in Nothing for field & prop.

The value of obj is passed down from above and is the result of a LINQ query (it is a single element of the list generated by the query):

    From bpt In CustomBProcessTypes Select text = bpt.Name(), value = bpt.Id

The value of name is also passed from above and is "Text" (note capitalization). I can examine obj in the debugger and confirm that the fieldnames of the object created by the LINQ query are 'text' and 'value' (note lack of capitalization) which is what I would expect.

So failure to find the field by the capitalized name makes sense. However, our production builds and my coworkers builds do not have this problem.

Because calls to type.getfield(string) are expressly cas-sensitive, the only thing I can think of at this point is there must be some configuration of LINQ relating to auto-capitalization of column/fieldnames, and my environment is not set up the same as the others.

Using visual studio 2012. I don't know much of anything about LINQ, per se.

Anyone have any idea what could be going on here?

(NOTE: if I can get an opportunity, I'll have a coworker step through the relevant code and see if in their environment the object created by the linq query ends up with capitalized field names)

EDIT: I verified with a coworker in his debug build: his LINQ query creates a list of objects with field names "Text" and "Value", but on in my environment the LINQ query ends up with field names "text" and "value". The code is the same, but there must be something about how LINQ is configured in my environment which fails to auto-capitalize those field names, but which happens on their machines and in our production environment.

Was it helpful?

Solution 2

I have answered my own question (insofar as is possible). Boils down to a bug in LINQ/vb.net.

Fully explained at top of original post (edited in). Hope this saves someone time in the future.

OTHER TIPS

I suppose it is possible that some compiler settings are resulting in different capitalization. Normally this would make no difference because VB.NET is a case-insensitive language so obj.Text and obj.text both work just as well. But to use case insensitivity in reflection lookups, you need to specify it by including BindingFlags.IgnoreCase in the second parameter of GetField or GetProperty:

Dim field As FieldInfo = objectType.GetField(name,
    BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.IgnoreCase)

I'm confused as to where name is coming from, though. Some other code is getting the field name from reflection on the query? I didn't see where this was explained in your question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top