Two reasons: How do I execute myQuery if it’s not within a sub? Also, if the Dim myQuery is within a sub, it’s recognized as System.Linq.IQueryable(Of <anonymous type>); elsewhere it’s only Object.
I’ve tried the following:
VB.NET:
Module Module1
Public myQuery = Nothing
Sub MakeQuery()
myQuery = From p in db.Persons…
Sub UseQuery()
For each pq in MyQuery…
Everything seems to work OK. However, myQuery is recognized only as Object.
The new extension methods such as Count are not available.
This is what prompted my post: If .Count is not available, how do I determine if the query returned no items?
Private myQuery As System.Linq.IQueryable(Of <Insert your datatype used here (likely String)>)
Sub MakeQuery()
myQuery = From p in db.Persons ...
...
End Sub
Sub UseQuery()
For Each pq In MyQuery ...
...
End Sub
The only time you should use Public is if you need to make the variable or procedure available outside your own program, as you would in a library for example. Otherwise try to stick to Private and Friend.
this causes drastic complaints - the whole module is invalid:
VB.NET:
Private myQuery As System.Linq.IQueryable(Of <String>)
@JohnH
I tried Selecting to New Output With ...
I was hopeful with this because it sounded like a new object would be created.
But I could not do anything with Output. It's only a Data Type, not an object.
Is there a way to make it an object?
It's obvious that I haven't read all the manuals, but I'm happy to see effective results with Linq to SQL.
I'm developing my first SQL application.
Do you know of another way to get count of a Linq query?
When you use the New keyword new objects are created, the difference is "New With" compiler creates and infers an anonymous type and "New <your type> With" creates an object of <your type>. The latter is the named type that you have to define first. The With part is used to set properties of the object.
Public Class ParentData1
Property firstName As String
Property personIDChild As Integer
Property personIDDad As Integer
Property personIDMom As Integer
Property mateID As Integer
End Class
Sub MakeQuery()
...
Select New ParentData1 With {.firstName = p.firstName, .personIDChild = parents.personIDChild, _
.personIDDad = parents.personIDDad, .personIDMom = parents.personIDMom, _
.mateID = m.mateID}
I don’t understand where the objects are stored for later access.
For comparison, this is a way to instantiate objects for class Person1.
VB.NET:
Public Class person1
Property firstName As String
Property lastName As String
End Class
Module Module2
Dim person1Col As New Collection
Sub MakeObjects(ByVal _firstName As String, ByVal _lastName As String)
Dim person1 As New Person1 With {.firstName = _firstName, .lastName = _lastName}
person1Col.Add(person1)
End Sub
The objects are stored in person1Col.
In the Linq query, what is the object container?
That article describes the difference between Immediate and Deferred execution (see below).
It does not address named types; it does not answer the immediate question.
You stated: “A new ParentData1 object is created for each match in query.”
I replied: “I don’t understand where the objects are created.
In the Linq query, what is the object container?”
The article says in part:
Query execution is separate from creating a query. After a query is created, its execution is triggered by a separate mechanism. A query can be executed as soon as it is defined (immediate execution), or the definition can be stored and the query can be executed later (deferred execution).
By default, when you create a query, the query itself does not execute immediately. Instead, the query definition is stored in the variable that is used to reference the query result. When the query result variable is accessed later in code, such as in a For…Next loop, the query is executed. This process is referred to as deferred execution. Introduction to LINQ in Visual Basic
' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}
' Query creation.
Dim evensQuery = From num In numbers
Where num Mod 2 = 0
Select num
' Query execution.
For Each number In evensQuery
Console.Write(number & " ")
Next
My first issue with the article is “the query can be executed later”.
What does “later” mean? My interpretation is: in another Sub that’s called later.
That’s what my main question relates to: “how can the results be made available to other procedures?”
For this to happen, the Dim must be module-wide, correct?
VB.NET:
Module
Dim Query1 = Nothing
Sub MakeQuery()
Query1 = From num In numbers ‘query is modified here
…
Sub UseQuery()
For each p in Query1…
The availability of Query1 “later” is not affected by “anonymous” or “named” type options.
The second issue is “the query itself does not execute immediately”.
This is saying the query itself does not generate objects.
Only when the query is executed (e.g. in a For Each loop) is the query executed.
Contrary to your statement “A new ParentData1 object is created for each match in query.”
I don’t see objects created unless my explicit code does it.
As a novice, I see these steps to create objects from a Linq to SQL query:
VB.NET:
Public Class Person1
Property firstName As String
Property lastName As String
End Class
Module Module2
Dim db As New MyFamilyDataContext
Dim person1Col As New Collection
Sub dbGetData3()
'SQL table Person2
Dim Query3 = From p In db.Person2s
Select p.firstName, p.lastName 'anonymous type
Dim cnt = Query3.Count 'Query is declared locally; .Count is available
For Each p In Query3
MakeObject(p.firstName, p.lastName) 'Makes instance of class Person1
Next
End Sub
Sub MakeObject(ByVal firstName As String, ByVal lastName As String)
Dim person1 As New Person1 With {.firstName = firstName, .lastName = lastName}
person1Col.Add(person1)
End Sub
The person1Col collection is available for later queries.
The “extra” code is class Person1, not needed otherwise.
This code seems to work and answers my original question.
If there is an easier or better way to do this with “named types” that I fail to understand, please let me know.
Well, how can there be a match in query if you don't execute the query? There may not be a match, but if there is the query states that instances is created when you use the New keyword.
Writing Linq queries is not any different that writing a SQL statement, for example "SELECT firstName FROM Person", writing this query (a plain string) will not connect to database and execute the command, only when you do that is the query executed and database can return result set. The article link explains when Linq query is executed.
The availability of Query1 “later” is not affected by “anonymous” or “named” type options.
Yes it is, because you can't declare the variable type if the result is an anonymous type, you can only use Object type and that is not something you can work with later.
If there is an easier or better way to do this with “named types” that I fail to understand, please let me know.
Yes, you can use a Linq query with a named type, like you posted before:
result = From p In db.Person2s Select New Person With {.firstName = p.firstName}
result type is IQueryable(Of Person) as I can infer from you posts, and Person instances are created each time you execute the query.
If you want to execute the query right away, or perhaps avoid executing the query multiple times, you can execute and convert result set to a list or array using ToList or ToArray for example, this was also explained in article.
I would like to address only one point in this post, relating to the “later” question.
The article explained three main parts:
VB.NET:
' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}
' Query creation.
Dim evensQuery = From num In numbers
Where num Mod 2 = 0
Select num
' Query execution.
For Each number In evensQuery
Console.Write(number & " ")
Next
I thought when it said “later”, the Query deferred execution could reside in a separate Sub procedure, called as needed. But for this to occur, the Query must have Module scope. And in that sense, the “anonymous” or “named” type options within the Query definition do not matter. That’s what I meant in:
The availability of Query1 “later” is not affected by “anonymous” or “named” type options.
Should the Query creation and Query execution always occur in the same procedure?
The example doesn’t provide that detail:
VB.NET:
Dim numberArray() = {0, 1, 2, 3, 4, 5, 6}
Dim evensQuery2 = From num In numberArray
Where num Mod 2 = 0
Select num
+++++++++++++++++++++++++++++++++++++++++ Execution #1 (++++ lines added by me)
Console.WriteLine("Evens in original array:")
For Each number In evensQuery2
Console.Write(" " & number)
Next
Console.WriteLine()
+++++++++++++++++++++++++++++++++++++++++ Change data
' Change a few array elements.
numberArray(1) = 10
numberArray(4) = 22
numberArray(6) = 8
+++++++++++++++++++++++++++++++++++++++++ Execution #2
' Run the same query again.
Console.WriteLine(vbCrLf & "Evens in changed array:")
For Each number In evensQuery2
Console.Write(" " & number)
Next
Console.WriteLine()
In a business application, the “Change data” step details are certainly not known in advance.
Could the Query creation and Query execution (in same sub) be called each time data is changed?
Altho the creation step is needed only once, repeating it doesn’t hurt, correct?
Therefore, “later” execution does not require separate Sub procedures.
Obviously I’m working with very simple examples.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.