Simple LINQ question - how to iterate through a group? - vb.net

I need some help with a LINQ query in VB.Net, please.
I have this simple group statement:
Dim drivers = From d In DriversOwners _
Group d By Key = d.UnitNumber Into Group _
Select Key, DriverGroup = Group
This works, and returns me the data I need to work with. Now I want to iterate through the groups, using a For Each construct. like this:
For Each x In drivers
Next
However, the compiler is barking at me, telling me that the
"'x' is not accessible in this context because it is 'Friend'."
Anyone know what I am doing wrong here?
Thanks in advance.

After digging and digging, I finally found the answer to this problem. Talk about obtuse!
Enabling LINQ in a .NET Framework 3.5 Project
When you move a project to .NET
Framework 3.5, a reference to
System.Core and a project-level import
for System.Linq (in Visual Basic only)
are added automatically. If you want
to use LINQ features, you must also
turn Option Infer on (in Visual Basic
only) [my emphasis].
When I changed the target framework from 2.0 to 3.5, Visual Studio automatically added the System.Core assembly, and automatically imported the System.Linq namespace. Now why in the world did it not also set Option Infer to "On" as well?
http://msdn.microsoft.com/en-us/library/bb398197.aspx

Looks to me like the variable x was declared earlier - as a class field, a method parameter, or a local variable.
Am I right?

I'm not sure if you've solved this or not. I had the exact same problem today and what ended up working for me was to not use a single-letter variable in the For Each loop. My code was the same as yours:
For Each x In a
...
Next
When I changed the code to the following it worked:
For Each retVal in a
...
Next
I also found the same 'Friend' error behavior for any single-letter variable.
I have no idea why it behaves this way, but I thought I'd pass this along in case this question is still out there.

Related

EnableCors for VB.net

Does anyone know how to put the enableCors into the controller on vb.net. i am working along with a pluralsight course and tried a code translator with no luck. my attempt is below.
<EnableCors(origins: "http://localhost:53080", headers: "*", methods: "*")>
The correct syntax would be something like this:
<EnableCors("http://localhost:53080", "*","*")>
The C# example appears to use named parameters. VB.NET supports that too, however the EnableCorsAttributes has properties and contractor arguments that only differ by letter casing. This confuses the compiler as to whether you are attempting to set the named parameter or the property in the attribute. So, in this case we can just drop the named arguments all together.
In Vb.net this <EnableCors("http://localhost:53080", "*","*")> will work, but, you have to add on NuGet the Microsoft.AspNet.WebApi.Cors and Microsoft.AspNet.Cors. You need to add Imports System.Web.Http.Cors on the class.
Remove any empty line between the http://localhost:53080", "*","*")> and the declaration of the controller class.

Using Excel-DNA with VS2005

I'm trying to use Excel-DNA to integrate my VB.NET DLL into VBA. But I'm running into the following problem. If I try to add this line before one of my static (Shared) class functions:
<ExcelFunction(Description = "Do stuff", Category = "Useful functions")> _
I get a compile error saying "Name 'Description' is not declared" (and same for Category). I've got VS2005 so maybe that has something to do with it. The example given in the Excel-DNA documentation is for C# and I'm feeling that maybe I just need to get the syntax right.
I've got the needed
Imports ExcelDna.Integration
line at the beginning of my file.
The syntax for using attributes in VB.NET is a bit different to C#. You need to write the property assignments with ":=", something like this:
<ExcelFunction(Description:="Do Stuff", Category:="Useful functions")>_
...

Empty Structures compile in VB 10+

This is at least a documentation error, if not a bug.
In VB.NET prior to .NET 4.0 (i.e. VB.NET 7 through 9) an empty Structure declaration fails at compile-time with
error BC30281: Structure 'MySimpleEmpty' must contain at least one instance member variable or Event declaration.
E.g. The following two structures compile successfully in VB10, and not prior:
Structure MySimpleEmpty
End Structure
Public Structure AnotherEmpty
Public Const StillEmpty As Boolean = True
End Structure
I note the documentation for the Error BC30281 stops at VB9, but the documentation for the Structure statement still has the datamemberdeclarations as required even as of VB11 (.NET 4.5 VS2012).
These two Structures compile in VB11 (VS2012) as well. (Thanks John Woo.)
Is there some blog entry or documentation confirming this is an intended change or a bug in VB10 and later?
Microsoft have marked this as a fixed bug, without actually stating what was fixed.
The VB11 (VS2012) documentation now says the datamemberdeclarations are optional in the grammar, but in the Parts table it says "Required. Zero or more..."!
I guess that's a fix... The VB10 (VS2010) documentation hasn't been changed.

VB.net can't find by string

Using VB.net, the following snippet gives the error below.
Dim _account = Account.Find(Function(x As Account) x.AccountName = txtFilterAccountName.Text)
or similarly if I do
.SingleOrDefault (Function(x As Account) x.AccountName = txtFilterAccountName.Text)
will both give the error "The method 'CompareString' is not supported". If I make the same call searching for an integer (ID field) it works fine.
.SingleOrDefault (Function(x As Account) x.Id = 12)
So integer matching is fine but strings don't work Is this a problem with the VB.net templates?
No this is not a problem with Vb.Net templates.
The problem is that you are not using a normal LINQ provider. Based on your tag (subsonic) I'm guessing you're using a LINQ to SQL query.
The problem is that under the hood, this is trying to turn your code into an expression tree which is then translated into an SQL like query. Your project settings are turning your string comparison into a call in the VB runtime. Specifically, Microsoft.VisualBasic.CompilerServices.Operators.CompareString.
The LINQ2SQL generater in question or VB compiler (can't remember where this check is done off the top of my head) does not understand how to translate this to an equivalent bit of SQL. Hence it generates an error. You need to use a string comparison function which is supported by LINQ2SQL.
EDIT Update
It looks like the CompareString operator should be supported in the Linq2SQL case. Does subsonic have a different provider which does not support this translation?
http://msdn.microsoft.com/en-us/library/bb399342.aspx
The problem is with SubSonic3's SQL generator and the expression tree generated from VB.NET.
VB.NET generates a different expression tree as noted by JaredPar and SubSonic3 doesn't account for it - see Issue 66.
I have implemented the fix as described but it has yet to merge into the main branch of SubSonic3.
BlackMael's fix has been committed:
http://github.com/subsonic/SubSonic-3.0/commit/d25c8a730a9971656e6d3c3d17ce9ca393655f50
The fix solved my issue which was similar to John Granade's above.
Thanks to all involved.

Store Variable Name in String in VB.NET

I'm trying to store the names of some variables inside strings. For example:
Dim Foo1 as Integer
Dim Foo1Name as String
' -- Do something to set Foo1Name to the name of the other variable --
MessageBox.Show(Foo1Name & " is the variable you are looking for.")
' Outputs:
' Foo1 is the variable you are looking for.
This would help with some debugging I'm working on.
Well, you can clearly just set Foo1Name = "Foo1" - but I strongly suspect that's not what you're after.
How would you know which variable you're trying to find the name of? What's the bigger picture? What you want may be possible with reflection, if we're talking about non-local variables, but I suspect it's either not feasible, or there's a better way to attack the problem in the first place.
Does this example from msdn using reflection help?
One solution would be to use an associative array to store your variables. Once, I did this in .Net, but I think I wrote a custom class to do it.
myArray("foo1Name") = "foo1"
Then, you can just store a list of your variable names, or you can wrap that up in the same class.
if( myArray(variableName(x)) == whatImLookingFor ) print variableName(x) & "is it"
I think this really depends on what you are trying to debug. Two possible things to look at are the Reflection and StackTrace classes. That said when your program is compiled, the compiler and runtime do not guarantee that that names need to be consistent with the original program.
This is especially the case with debug vs. release builds. The point of the .PDB files (symbols) in the debug version are to include more information about the original program. For native C/C++ applications it is strongly recommended that you generate symbols for every build (debug+release) of your application to help with debugging. In .NET this is less of an issue since there are features like Reflection. IIRC John Robbins recommends that you always generate symbols for .NET projects too.
You might also find Mike Stall's blog useful and the managed debugger samples.
For finding the variable name, see: Finding the variable name passed to a function
This would apply to VB.Net as well.