嗔秤戻幣�哉膵�云利匈嬉蝕湊蛸賜�塋床四衲���萩晦編報炎嘔囚^泡仟 ̄云利匈��
VB2008貫秘壇欺娼宥(PDF鯉塀哂猟井)-及78何蛍
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何! 泌惚云慕短嗤堋響頼���誅卒亮茂�俊彭堋響��辛聞喘貧圭 "辺茄欺厘議箝誓匂" 孔嬬 才 "紗秘慕禰" 孔嬬��
alphabetical order。 The way that the Order By works is that the value of the variable is pared�察 �
rather than the actual variable。If you want to sort in reverse order�察�you can use the keyword
Descending�察�as follows�此�
Dim sortedWords = _
From w In words _
Order By w Descending _
Select w
This approach allows you to perform sorts according to other values。 For example�察�you
could sort by the length of word�察�like this�此�
Dim sortedWords = _
From w In words _
Order By w。Length _
Select w
´´´´´´´´´´´´´´´´´´´´´´Page 434´´´´´´´´´´´´´´´´´´´´´´´
412 CH AP T E R 1 5 * L E A R N I N G A B OU T L I N Q
The Order By queries for the value of w。Length�察�which returns a number。 If that number
happens to be longer or shorter than another word�察�it is placed after or before the other word。
You could also sort according to multiple criteria。 For example�察�you could sort the words
alphabetically and then by length�此�
Dim sortedWords = _
From w In words _
Order By w�察�w。Length _
Select w
To sort by multiple criteria�察�append them to the Order By keywords�察�each separated by
a ma。
*Note The alphabetical and length sort is fruitless�察�because when you sort alphabetically�察�you will auto
matically sort by length。 The example is just for illustrative purposes。
Performing Set Operations
The last major topic that you need to know about when using LINQ is the ability to perform set
operations on a collection。 The major downside�察�however�察�to performing set operations is that
you must use the methods�察�and at the time of this writing�察�no LINQ mand syntax existed for
set operations。
Knowing about set operations is useful because they enable you to sort and organize multiple
result sets。 The examples in this section involve the Customer type again。 However�察�to make
sure that the set operations function properly�察�you need to implement the Equals�┌� and
GetHashCode�┌� methods�察�like this�此�
Friend Class Customer
Public Overrides Function Equals��ByVal obj As Object�� As Boolean
If TypeOf obj Is Customer Then
Dim otherObj As Customer = TryCast��obj�察�Customer��
If otherObj。Identifier。pareTo��Identifier�� = 0 Then
Return True
End If
End If
Return False
End Function
Public Overrides Function GetHashCode�┌� As Integer
Return Identifier。GetHashCode�┌�
End Function
Public Overrides Function ToString�┌� As String
Return String。Concat��New Object�┌� _
��;Identifier �─┌察�Me。Identifier�察 ┌� Points �─┌察�Me。Points�察 ┌�;����
End Function
´´´´´´´´´´´´´´´´´´´´´´Page 435´´´´´´´´´´´´´´´´´´´´´´´
CH AP T E R 1 5 * L E A R N I N G A B OU T L I N Q 413
Public Identifier As String
Public Points As Integer
End Class
*Note The GetHashCode�┌� implementation here is rudimentary。 In the source code that es with this
book�察�you will find a GetHashCode library class�察�which makes it simpler to implement GetHashCode�┌�。 The
source code is in the project ServerSideSpreadsheet/Devspace。Trader。mon/Automators。
Look at how GetHashCode�┌� and Equals�┌� are implemented。 Notice that the points data
member is ignored。 In the case of a customer�察�this is acceptable�察�because a customer with iden
tical identifiers but unequal points does not imply two separate customers。
Implementing Equals�┌� and GetHashCode�┌� for custom types is absolutely imperative�察�because
the set operations use that information to determine whether two objects are identical。 If you
don¨t implement either method�察�the set operations will use the default implementations of
Equals�┌� and GetHashCode�┌��察�which are inplete and will give you the wrong results。
The next step is to create two separate lists of customers。 In this example�察�both lists contain the
same valued customer。 Realize that the identical customer is not the same object instance�察�but
contains the same values。
Dim customers1 As Customer�┌� = New Customer�┌� �� _
New Customer�┌� With ��。Identifier = ;Person 1;�察 �Points = 0���察�_
New Customer�┌� With ��。Identifier = ;Person 2;�察 �Points = 10����
Dim customers2 As Customer�┌� = New Customer�┌� �� _
New Customer�┌� With ��。Identifier = ;Person 3;�察 �Points = 0���察�_
New Customer�┌� With ��。Identifier = ;Person 2;�察 �Points = 10����
To get a list of all unique customers�察�you can use Union�┌��察�as follows�此�
Dim uniqueCustomers = customers1。Union��customers2��
Contained within the list represented by the variable uniqueCustomers will be the three
customers of the two lists。
Using LINQ in Other Contexts
So far�察�all of the examples in this chapter involved using LINQ and objects。 However�察�LINQ is
not just an object´searching technology。 It is also usable with XML and relational databases。
Using LINQ with these other data sources is not a problem�察�since the querying is identical。
What is a problem is getting the query to work in the first place。
Consider Figure 15´1�察�which illustrates the LINQ architecture。
As you can see in Figure 15´1�察�all programming languages can access the LINQ
library。 The data manipulated by the LINQ library es from what is called a LINQ´enabled
data source。 The examples that you¨ve seen use the LINQ to objects data source。
´´´´´´´´´´´´´´´´´´´´´´Page 436´´´´´´´´´´´´´´´´´´´´´´´
414 CH AP T E R 1 5 * L E A R N I N G A B OU T L I N Q
Figure 15´1。 LINQ architecture ��based on an image in MSDN Magazine�察�http��//msdn。microsoft。/
msdnmag/issues/07/06/csharp30/default。aspx��
However�察�there is also the possibility to use a LINQ´enabled ADO connection。 The
good news is that you can use LINQ with a relational database。 The bad news is that the rela
tional database¨s ADO driver must support the special LINQ characteristics。 At the time
of this writing�察�only the Microsoft SQL Server driver supports LINQ。 Currently�察�the drivers for
Microsoft Access�察�MySQL�察�and other relational databases do not support LINQ。
Consider this LINQ query�此�
Dim northwind As NorthwindDataContext = _
New NorthwindDataContext�┌�
Dim products = From p In northwind。Products _
Where p。OrderDetails。Count = 0 And p。UnitPrice 〃 100 _
Select p
Notice the code in the From statement。 The data source is an object that references the rela
tional database Products table。 If a database driver is optimized for LINQ�察�it will understand the
LINQ query and optimize it as if it were a SQL statement。
If your database driver does not support LINQ�察�then you have a problem because�察�in theory�察 �
you would need to download all the data from the table�察�and then execute the LINQ query。 That
would waste resources and is not remended。
´´´´´´´´´´´´´´´´´´´´´´Page 437´´´´´´´´´´´´´´´´´´´´´´´
CH AP T E R 1 5 * L E A R N I N G A B OU T L I N Q 415
*Note For examples of LINQ using relational databases�察�see Beginning VB 2008 Databases by Vidya Vrat
Agarwal and James Huddleston ��Apress�察�2008��。
Let¨s say that you want to execute LINQ on an XML document。 Consider the following
XML LINQ code ��from http��//hookedonlinq。/LINQtoXML5MinuteOverview。ashx��。
Dim loaded As XDocument = XDocument。Load�─�C��contacts。xml;��
' Query the data and write out a subset of contacts
Dim q = From c In loaded。Descendants�─�contact;�� _
Where CType��c。Attribute�─�contactId;��。Value�察�Integer�� ゞ 4 _
Select c。Element�─�firstName;��。ToString�┌� & ; ; & _
c。Element�─�lastName;��。ToString�┌�
Notice how the same LINQ syntax that you¨ve seen in the previous examples is used�察�but
the source of the data that is to be manipulated by LINQ is different。 Keep in mind that when
you are manipulating data using LINQ�察�you are manipulating objects that may point to XML
files�察�relational databases�察�or plain´vanilla data objects。
The Important Stuff to Remember
In this chapter�察�you learned about the basics of LINQ and how to write queries。 Here are the key
points to remember�此�
o LINQ is an API that sits on top of other technologies such as Visual Basic objects�察�rela
tional databases�察�and XML documents。
o LINQ can work effectively only if the underlying data source technology has been opti
mized for LINQ。 Otherwise�察�you are left with having to load a single record set and then
manipulate that record set。
o Regardless of the data source�察�the techniques used to query and write LINQ are identical。
o When manipulating LINQ objects�察�the methods and properties associated with the
various data sources are different。 For example�察�when searching XML documents�察�you
can use XML Document Object Model ��DOM�� methods and properties that are not avail
able when manipulating plain´vanilla objects。
o LINQ is not just a syntax�察�but a series of extension methods associated with sets of data。
The methods allow for more sophisticated data pipelining and processing of
information。
´´´´´´´´´´´´´´´´´´´´´´Page 438´´´´´´´´´´´´´´´´´´´´´´´
416 CH AP T E R 1 5 * L E A R N I N G A B OU T L I N Q
Some Things for You to Do
The following are two exercises to help you apply what you¨ve learned in this chapter。
1。 The solution for finding a frequency presented in this chapter went from text to text to
calculate the statistics。 Can you think of another approach that would require minimal
changes in the interface structure�拭�Hint�此�the way the objects were parsed into objects
borrowed code from another application。 Could that other application be used somehow�拭 �
2。 You saw a LINQ query embedding another LINQ query when finding the frequency of
two numbers。 Rewrite the code to generate the frequency of all binations of single�察 �
pairs�察�and triples。
´´´´´´´´´´´´´´´´´´´´´´Page 439´´´´´´´´´´´´´´´´´´´´´´´
C H A P T E R 1 6
* * *
Learning About Other Visual
Basic Techniques
This last chapter in the book is about tying up loose ends。 The techniques discussed in this
chapter are those that you will use in specific situations。 This chapter covers the following
topics�此�
o How to use arithmetic operators to manipulate numbers
o How to overload operators
o When you might use the GoTo statement
o How to use generics constraints
o How to use nullable types
o How to use partial classes and methods
Operators
You have seen various operators used in examples throughout the book�察�such as the assignment
operator ��a = 3���察�and the logical operators �─�If�─�a = b����。 Visual Basic has many more arithmetic
operators that you can use to process types。 You can also define custom operators。
Using Arithmetic Operators
The subtraction �─ ����察�multiplication ��*���察�and division ��/�� operators are typically applicable to
only numeric values。 These operators are directly parable to the mathematical operators
you learned about in elementary school。 Let¨s look at what the other arithmetic operators do。
Addition
The addition �┌��� operator is used to indicate the addition of two values�察�like this�此�
a = c �� 1
The addition has a left´hand side and right´hand side�察�separated by the equal sign ��=��。
On the right´hand side�察�the variable c is added to 1 and assigned to the variable a。
417
´´´´´´´´´´´´´´´´´´´´´´Page 440´´´´´´´´´´´´´´´´´´´´´´´
418 CH AP T E R 1 6 * L E A R N I N G A B OU T O TH E R V IS U AL B A SI C TE C H N IQ U E S
The notion of a left´hand side and a right´hand side as two separate parts is important
when you consider this code�此�
a = a �� 1
In the example�察�the variable a is added with the value 1 and assigned to the variable a�察�but
these operations do not happen at the same time�察�they happen sequentially。 First�察�the right
hand side is executed�察�and then the left´hand side is executed。 By executing the left´hand side�察 �
the existing value of the variable a is overwritten。
Let¨s consider another example�此�
b = a = a �� 1
If you were to run this code�察�b would not be assigned�察�because the example has mixed
operators�察�which translates to this�此�
Dim b As Integer = CInt�─��┌�a = ��a �� 1���� 〃 False����
The result is not what you expected�察�and not even close to what you were trying to achieve
��and isn¨t even allowed with Option Strict set to On��。 What this illustrates is that you need to be
careful with operators。
Bitwise Operators
Bitwise operators are used to access and manipulate individual bits in a whole number。
As you learned in Chapter 2�察�the puter sees numbers as binary�察�with only two unique
identifiers。 Thus�察�whole numbers could be viewed as arrays of Boolean values�察�as there are only
two valid values�此�1 and 0 or True and False。
Let¨s look at example of using the bitwise operators。 Say that you want to know whether a
person is tall�察�wears hats�察�and runs slowly。 Using Boolean data members�察�you would write the
following code。
Class PersonWithAttributes
Public IsPersonTall As Boolean
Public WearsHats As Boolean
Public RunsSlowly As Boolean
E
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何!
梁椣戻幣�� 梁心弌傍議揖扮窟燕得胎��傍竃徭失議心隈才凪万弌誌育断蛍�輌臆惨軼僑〃�燕慕得珊辛參資誼持蛍才将刮襲潜��範寔亟圻幹慕得 瓜寡追葎娼得辛參資誼寄楚署衛、持蛍才将刮襲潜填��