饭饭TXT > 学习管理 > 《Visual Studio 2010 高级编程(英文出书版)》作者:Nick Randolph/等【完结】 > [Visual.Studio.2010.高级编程].Professional.Visual.Studio.2010.txt

第 88 页

作者:Nick Randolph/等 当前章节:15367 字 更新时间:2026-6-18 14:51

can potentially lead to some issues in debugging and some unexpected performance issues if you are

executing the query multiple times. In the code you have seen so far, you have declared the LINQ

statement and then passed the results object to the ObjectDumper, which in turn iterates through

the query results. If you were to repeat this call to the ObjectDumper, it would again iterate

through the results.

Unfortunately, this delayed execution can mean that LINQ statements are hard to debug. If you

select the statement and insert a breakpoint, all that will happen is that the application will stop

where you have declared the LINQ statement. If you step to the next line, the results object will

simply state that it is an “In-Memory Query.” In C# the debugging story is slightly better because

you can actually set breakpoints within the LINQ statement. As you can see from Figure 28-8,

the breakpoint on the conditional statement has been hit. From the call stack you can see that

the current execution point is no longer actually in the FinalQuery method; it is in fact within the

ObjectDumper.Write

method.

fiGure 28-8

If you need to force the execution of a LINQ you can call ToArray or ToList on the results

object. This will force the query to execute, returning an Array or List of the appropriate type.

You can then use this array in other queries, reducing the need for the LINQ to be executed

multiple times.

linQ to XMl .

597

When setting a breakpoint within a LINQ in C# you need to place

the cursor at the point you want the breakpoint to be set and press F9 (or

use the right-click context menu to set a breakpoint), rather than clicking in

the margin. Clicking in the margin sets a breakpoint on the whole LINQ,

which is not what you want.

linq to xMl

If you have ever worked with XML in .NET, you will recall that the object model isn’t as easy

to work with as you would imagine. For example, to create even a single XML element you need to

have an XmlDocument:

Dim x as New XmlDocument

x.AppendChild(x.CreateElement("Customer"))

As you will see when you start to use LINQ to query and build XML, this object model doesn’t

allow for the inline creation of elements. To this end, a new XML object model was created that

resides in the System.Xml.Linq assembly presented in Figure 28-9.

fiGure 28-9

As you can see from Figure 28-9, there are classes that correspond to the relevant parts of an XML

document: XComment, XAttribute, and XElements. The biggest improvement is that most of the

classes can be instantiated by means of a constructor that accepts Name and Content parameters.

In the following C# code, you can see that an element called Customers has been created that

contains a single Customer element. This element, in turn, accepts an attribute, Name, and a series

of Order elements.

c#

XElement x = new XElement("Customers",

new XElement("Customer",

new XAttribute("Name","Bob Jones"),

598 .

chaPter 28 lAnguAge inTegrATed QuerieS (linQ)

new XElement("Order",

new XAttribute("Product", "Milk"),

new XAttribute("Quantity", 2)),

new XElement("Order",

new XAttribute("Product", "Bread"),

new XAttribute("Quantity", 10)),

new XElement("Order",

new XAttribute("Product", "Apples"),

new XAttribute("Quantity", 5))

)

);

Though this code snippet is quite verbose and it’s hard to distinguish the actual XML data from

the surrounding .NET code, it is significantly better than with the old XML object model, which

required elements to be individually created and then added to the parent node.

While it is possible to write the same code in VB using the XElement and

XAttribute constructors, the support for XML literals (as discussed in the next

section) makes this somewhat redundant.

Vb xMl literals

One of the biggest innovations in the VB language is the support for XML literals. As with strings

and integers, an XML literal is treated as a first-class citizen when you are writing code. The

following snippet illustrates the same XML generated by the previous C# snippet as it would appear

using an XML literal in VB:

Vb

Dim cust = < Customers >

< Customer Name="Bob Jones" >

< Order Product="Milk" Quantity="2"/ >

< Order Product="Bread" Quantity="10"/ >

< Order Product="Apples" Quantity="5"/ >

< /Customer >

< /Customers >

Not only do you have the ability to assign an XML literal

in code, you also get designer support for creating and

working with your XML. For example, when you enter

the

closing XML tag for you. Figure 28-10 illustrates how

the Customers XML literal can be condensed in the same

fiGure 28-10

way as other code blocks in Visual Studio 2010.

You can also see in Figure 28-10 that there is an error in the XML literal being assigned to the

data variable. In this case there is no closing tag for the Customer element. Designer support is

invaluable for validating your XML literals, preventing run time errors when the XML is parsed

into XElement objects.

on a new element, it will automatically create the >

linQ to XMl .

599

Paste xMl as xelement

Unfortunately, C# doesn’t have native support for XML literals, which makes generating XML

a painful process, even with the new object model. Luckily, there is a time-saving add-in that

will paste an XML snippet from the clipboard into the code window as a series of XElement

objects. This can make a big difference if you have to create XML from scratch. The add-in,

PasteXmlAsLinq in the LinqSamples folder, is available in the C# samples that ship with

Visual Studio 2010. Simply open the sample in Visual Studio 2010, build the solution, navigate

to the output folder, and copy the output files (namely

PasteXmlAsLinq.Addin and PasteXmlAsLinq.dll) to the

add-ins folder for Visual Studio 2010. When you restart Visual

Studio 2010 you will see a new item, Paste XML as XElement, in

the Edit menu when you are working in the code editor window,

as you can see in Figure 28-11. fiGure 28-11

Visual Studio 2010 looks in a variety of places, defined in the Options dialog

(Tools menu), for add-ins. Typically, it looks in an add-ins folder located beneath

the Visual Studio root documents directory. For example: C:\users\username\

Documents\Visual Studio 2010\Addins. If the Addins folder doesn’t exist,

you may need to create it.

To work with this add-in, all you need to do is to

create the XML snippet in your favorite XML editor.

In Figure 28-12 we have used XML Notepad, which

is a freely available download from www.microsoft.

com, but you can also use the built-in XML editor

within Visual Studio 2010.

Once you have created the XML snippet, copy it to

the clipboard (for example, by pressing Ctrl1C). Then

place your cursor at the point at which you want

to insert the snippet within Visual Studio 2010 and

select Paste XML as XElement from the Edit menu.

(Of course, if you use this option frequently you may

want to assign a shortcut key to it so that you don’t

have to navigate to the menu.) The code generated by

the add-in will look similar to the following:

c#

XElement xml = new XElement("Customers",

new XElement("Customer",

new XAttribute("Name", "Bob Jones"),

new XElement("Order",

new XAttribute("Product", "Milk"),

new XAttribute("Quantity", "2")

fiGure 28-12

600 .

chaPter 28 lAnguAge inTegrATed QuerieS (linQ)

),

new XElement("Order",

new XAttribute("Product", "Bread"),

new XAttribute("Quantity", "10")

),

new XElement("Order",

new XAttribute("Product", "Apples"),

new XAttribute("Quantity", "5")

)));

Code snippet MainForm.cs

creating xMl with linq

Although creating XML using the new object model is significantly quicker than previously

possible, the real power of the new object model comes when you combine it with LINQ in the

form of LINQ to XML (XLINQ). By combining the rich querying capabilities with the ability to

create complex XML in a single statement, you can now generate entire XML documents in a single

statement. Let’s continue with the same example of customers and orders. In this case you have an

array of customers, each of whom has any number of orders. What you want to do is create XML

that lists the customers and their associated orders. You’ll start by creating the customer list, and

then introduce the orders.

To begin with, create an XML literal that defines the structure you want to create:

c#

XElement customerXml = new XElement("Customers",

new XElement("Customer",

new XAttribute("Name", "Bob Jones")));

Vb

Dim customerXml = <Customers>

<Customer Name="Bob Jones">

</Customer>

</Customers>

Although you can simplify this code by condensing the Customer element into <Customer

Name=”Bob Jones” />, you’re going to be adding the orders as child elements, so you will use a

separate closing XML element.

expression Holes

If you have multiple customers, the Customer element is going to repeat for each one, with Bob

Jones being replaced by different customer names. Before you deal with replacing the name, you

first need to get the Customer element to repeat. You do this by creating an expression hole, using a

syntax familiar to anyone who has worked with ASP:

linQ to XMl .

601

c#

XElement customerXml = new XElement("Customers",

from c in customers

select new XElement("Customer",

new XAttribute("Name",

"Bob Jones")));

Vb

Dim customerXml = <Customers>

<%= From c In customers _

Select <Customer Name="Bob Jones">

</Customer> %>

</Customers>

Here you can see that in the VB code, <%= %> has been used to define the expression hole, into

which a LINQ statement has been added. This is not required in the C# syntax because the LINQ

statement just becomes an argument to the XElement constructor. The Select statement creates

a projection to an XML element for each customer in the Customers array, based on the static

value “Bob Jones”. To change this to return each of the customer names you again have to use an

expression hole. Figure 28-13 shows how Visual Studio 2010 provides rich IntelliSense support in

these expression holes.

fiGure 28-13

The following snippet uses the loop variable Name so that you can order the customers based on

their full names. This loop variable is then used to set the Name attribute of the customer node.

c#

XElement customerXml = new XElement("Customers",

from c in customers

let name = c.FirstName + " " + c.LastName

orderby name

select new XElement("Customer",

new XAttribute("Name", name),

from o in c.Orders

select new XElement("Order",

new XAttribute("Product", o.Product),

new XAttribute("Quantity",

o.Quantity))));

Code snippet MainForm.cs

602 .

chaPter 28 lAnguAge inTegrATed QuerieS (linQ)

Vb

Dim customerXml = <Customers>

<%= From c In customers _

Let Name = c.FirstName & “ “ & c.LastName _

Order By Name _

Select <Customer Name=<%= Name %>>

<%= From o In c.Orders _

Select

<Order

Product=<%= o.Product %>

Quantity=<%= o.Quantity %>

/> %>

</Customer> %>

</Customers>

Code snippet MainForm.vb

The other thing to notice in this snippet is that you have included the creation of the Order elements

for each customer. Although it would appear that the second, nested LINQ statement is independent

of the first, there is an implicit joining through the customer loop variable c. Hence, the second

LINQ statement is iterating through the orders for a particular customer, creating an Order element

with attributes Product and Quantity.

As you can see, the C# equivalent is slightly less easy to read but is by no means more complex.

There is no need for expression holes, because C# doesn’t support XML literals; instead, the LINQ

statement just appears nested within the XML construction. For a complex XML document this

would quickly become difficult to work with, which is one reason VB now includes XML literals as

a first-class language feature.

queryinG xMl

In addition to enabling you to easily create XML, LINQ can also be used to query XML. The

following Customers XML is used in this section to discuss the XLINQ querying capabilities:

<Customers>

<Customer Name="Bob Jones">

<Order Product="Milk" Quantity="2"/>

<Order Product="Bread" Quantity="10"/>

<Order Product="Apples" Quantity="5"/>

</Customer>

</Customers>

The following two code snippets show the same query using VB and C#, respectively. In both cases

the customerXml variable (an XElement) is queried for all Customer elements, from which the Name

attribute is extracted. The Name attribute is then split over the space between names, and the result

is used to create a new Customer object.

schema support .

603

c#

var results = from cust in customerXml.Elements("Customer")

let nameBits = cust.Attribute("Name").Value.Split(' ')

select new Customer() {FirstName = nameBits[0],

LastName=nameBits[1] };

目录
设置
设置
阅读主题
字体风格
雅黑 宋体 楷书 卡通
字体大小
适中 偏大 超大
保存设置
恢复默认
手机
手机阅读
扫码获取链接,使用浏览器打开
书架同步,随时随地,手机阅读
首 页 < 上一章 章节列表 下一章 > 尾 页