﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-麒麟.NET</title><link>http://www.cnblogs.com/kirinboy/</link><description /><language>zh-cn</language><lastBuildDate>Fri, 05 Sep 2008 18:41:02 GMT</lastBuildDate><pubDate>Fri, 05 Sep 2008 18:41:02 GMT</pubDate><ttl>60</ttl><item><title>【翻译】Data Access with LINQ to SQL (1) -- New C# and VB.NET Language Features</title><link>http://www.cnblogs.com/kirinboy/archive/2008/08/13/Data_Access_with_LINQ_to_SQL_1.html</link><dc:creator>麒麟.NET</dc:creator><author>麒麟.NET</author><pubDate>Wed, 13 Aug 2008 07:32:00 GMT</pubDate><guid>http://www.cnblogs.com/kirinboy/archive/2008/08/13/Data_Access_with_LINQ_to_SQL_1.html</guid><wfw:comment>http://www.cnblogs.com/kirinboy/comments/1266986.html</wfw:comment><comments>http://www.cnblogs.com/kirinboy/archive/2008/08/13/Data_Access_with_LINQ_to_SQL_1.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cnblogs.com/kirinboy/comments/commentRss/1266986.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/kirinboy/services/trackbacks/1266986.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p><em></em>&nbsp;
<p><em>该系列翻译自《ASP.NET Unleashed 3.5》第18章内容</em>
<p>&nbsp;
<p>在.NET Framework 3.5的众多新特性之中，LINQ to SQL是最重要的一个。实际上，它也许意味着自SQL诞生以来，应用程序与数据库的结合方式上最重大的一次变革。
<p>长期以来，程序员处理未持久化数据（应用程序）和持久化数据（数据库）的方式有着天壤之别：在应用程序中，我们使用对象和属性（用C#或VB.NET创建）；而在大多数数据库中，我们使用表和字段。
<p>不管我们的应用程序和数据库是否描述非常类似的数据，这都是事实。例如，你可能会拥有一个类和一个表，其名称均为Product，代表你的Web站点所销售的产品列表。尽管如此，在这些实体之间进行交互的语言（C#、VB.NET与SQL语言）却不尽相同。很多大公司都会拥有不同的开发人员，有的擅长C#或VB.NET，有的则专攻SQL。
<p>程序员要花费惊人的时间来转换对象和关系型世界，而这项工作是机械和乏味的。每当我想起花费在声明这些类（包含数据库字段到属性的映射）上的时间时，我都会不寒而栗。而这些时间我本可以用来陪孩子们逛公园、看电影或遛狗，等等。
<p>LINQ to SQL的诞生使得我们可以对SQL宣判死刑。或者更准确地说，它使得SQL语言走向幕后，我们再也不必使用SQL了。这是件好事。SQL已死！
<p>本章是较难的一章。LINQ to SQL并非很容易理解的概念，它依赖于C#、VB.NET以及.NET Framework中引入的一些新特性，而这些特性是不易掌握的。所以，请保持耐心，做个深呼吸。我保证最后一切都会清晰起来。
<p>本章分为4部分。在第一部分中，我们讨论C#、VB.NET和.NET Framework 3.5引入的支持LINQ的新特性。然后，你将学习如何使用LINQ to SQL实体描述数据库表。接下来，我解释如何使用LINQ to SQL执行标准SQL命令，如SELECT、INSERT、UPDATE和DELETE命令。在本章的最后部分，我将示范如何创建自定义实体类（包含数据有效性验证）。
<h3><strong>C#和VB.NET的新特性</strong></h3>
<p>微软公司为C#和VB.NET引入了诸多新的语言特性，以支持LINQ to SQL工作。很多特性都使得C#和VB.NET的行为更像动态语言（如JavaScript）。尽管引入的主要动机是支持LINQ，这些新特性本身还是非常有趣的。
<p><em>注意：要使用这些新特性，你需要使Web站点面向.NET Framework 3.5，确保项目中包含web.config文件。然后选择菜单选项Website&#224;Start Options&#224;Build，在Target Framework中选择.NET Framework 3.5。执行这些步骤将会修改你的web.config文件，使其引用必要的程序集并使用正确的C#或VB.NET版本。</em>
<h4><strong>理解自动属性</strong></h4>
<p>我们将探索的第一个新语言特性叫做自动属性（Automatic Properties）。不幸的是，只有C#支持该特性，VB.NET并不支持。
<p>自动属性提供了定义新属性的快速方法。如代码清单18-1所示，类Product包含了Id、Description和Price属性。
<p>代码清单 18-1 LanguageChanges\App_Code\AutomaticProperties.cs
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> AutomaticProperties
{
<span class="rem">// Automatic Properties</span>
<span class="kwrd">public</span> <span class="kwrd">int</span> Id { get; set; }
<span class="kwrd">public</span> <span class="kwrd">string</span> Description { get; set; }
<span class="rem">// Normal Property</span>
<span class="kwrd">private</span> <span class="kwrd">decimal</span> _Price;
<span class="kwrd">public</span> <span class="kwrd">decimal</span> Price
{
get { <span class="kwrd">return</span> _Price; }
set { _Price = <span class="kwrd">value</span>; }
}
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>注意前两个属性Id和Description，没有使用Getter和Setter，这与最后一个属性Price不同。C#编译器将为你自动创建Getter和Setter，以及与属性对应的私有字段。
<p>你不能向自动属性中的Getter和Setter添加任何逻辑，也不能创建只读的自动属性。
<p>自动属性怎么会和LINQ to SQL有关呢？在使用LINQ to SQL时，你为了得到数据的结构（类似SQL查询时使用select语句得到的列表），经常将类设计为仅包含数据库表的各个字段。因此，你肯定希望使用最小的工作量来创建属性列表，自动属性就是为此量身定做的。
<p><em>注意：使用Visual Web Developer或Visual Studio可以向类或页面中快速添加自动属性，你只需输入&#8220;prop&#8221;并按Tab键两次。</em>
<h3><strong>理解初始化器</strong></h3>
<p>使用初始化器（Initializers）可以减少实例化类的工作量。例如，假设你拥有如代码清单18-2（C#）或代码清单 18-3中的类（VB.NET）。
<p>代码清单 18-2 LanguageChanges\App_Code\Product.cs
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Product
{
<span class="kwrd">public</span> <span class="kwrd">int</span> Id { get; set; }
<span class="kwrd">public</span> <span class="kwrd">string</span> Name { get; set; }
<span class="kwrd">public</span> <span class="kwrd">decimal</span> Price { get; set; }
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>代码清单 18-3 LanguageChanges\App_Code\Product.vb
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Class</span> Product
<span class="kwrd">Private</span> _Id <span class="kwrd">As</span> <span class="kwrd">Integer</span>
<span class="kwrd">Public</span> <span class="kwrd">Property</span> Id() <span class="kwrd">As</span> <span class="kwrd">Integer</span>
<span class="kwrd">Get</span>
<span class="kwrd">Return</span> _Id
<span class="kwrd">End</span> <span class="kwrd">Get</span>
<span class="kwrd">Set</span>(<span class="kwrd">ByVal</span> value <span class="kwrd">As</span> <span class="kwrd">Integer</span>)
_Id = value
<span class="kwrd">End</span> <span class="kwrd">Set</span>
<span class="kwrd">End</span> <span class="kwrd">Property</span>
<span class="kwrd">Private</span> _Name <span class="kwrd">As</span> <span class="kwrd">String</span>
<span class="kwrd">Public</span> <span class="kwrd">Property</span> Name() <span class="kwrd">As</span> <span class="kwrd">String</span>
<span class="kwrd">Get</span>
<span class="kwrd">Return</span> _Name
<span class="kwrd">End</span> <span class="kwrd">Get</span>
<span class="kwrd">Set</span>(<span class="kwrd">ByVal</span> value <span class="kwrd">As</span> <span class="kwrd">String</span>)
_Name = value
<span class="kwrd">End</span> <span class="kwrd">Set</span>
<span class="kwrd">End</span> <span class="kwrd">Property</span>
<span class="kwrd">Private</span> _Price <span class="kwrd">As</span> <span class="kwrd">Decimal</span>
<span class="kwrd">Public</span> <span class="kwrd">Property</span> Price() <span class="kwrd">As</span> <span class="kwrd">Decimal</span>
<span class="kwrd">Get</span>
<span class="kwrd">Return</span> _Price
<span class="kwrd">End</span> <span class="kwrd">Get</span>
<span class="kwrd">Set</span>(<span class="kwrd">ByVal</span> value <span class="kwrd">As</span> <span class="kwrd">Decimal</span>)
_Price = value
<span class="kwrd">End</span> <span class="kwrd">Set</span>
<span class="kwrd">End</span> <span class="kwrd">Property</span>
<span class="kwrd">End</span> <span class="kwrd">Class</span>
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>Product类包含3个公共属性（由于C#有自动属性的优势，因此C#示例采用自动属性进行定义，而VB.NET示例采用普通方式进行定义）。
<p>现在，你需要创建一个Product类的实例，在.NET Framework 2.0中，采用以下方式（C#）：
<pre class="csharpcode">Product product1 = <span class="kwrd">new</span> Product();
product1.Id = 1;
product1.Name = &#8220;Laptop Computer&#8221;;
product1.Price = 800.00m;</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>VB.NET采用以下方式：
<pre class="csharpcode"><span class="kwrd">Dim</span> product1 <span class="kwrd">As</span> <span class="kwrd">New</span> Product()
product1.Id = 1
product1.Name = &#8220;Laptop Computer&#8221;
product1.Price = 800.0</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>注意，初始化一个简单的Product类使用了4行代码，这太浪费了。利用初始化器，这些工作可以用一行代码完成。用C#使用初始化器的代码如下：
<p>Product product2 = new Product {Id=1, Name=&#8221;Laptop Computer&#8221;, Price=800.00m};
<p>用VB.NET使用初始化器的代码如下：
<p>Dim product2 As New Product() With {.Id = 1, .Name = &#8220;Laptop Computer&#8221;,.Price = 800.0}
<p>在.NET Framework 2.0中，你可以声明Product类的构造函数，包含Id、Name和Price作为参数。但由于还需要在构造函数中将参数值赋给属性，因此导致了代码的膨胀。使用初始化器，你显然可以做类似的工作。并且，你还因此得到了好处：更加小巧的类，以及声明该类时使用的最少的代码。
<h4><strong>理解类型推断</strong></h4>
<p>一个新特性使得C#和VB.NET看上去非常像JavaScript之类的动态语言，这个特性就是局部变量类型推断（Type Inference）。当使用类型推断时，你允许C#或VB.NET编译器在编译时确定变量类型。
<p>下面的代码介绍了在C#中如何使用类型推断：
<p>var message = &#8220;Hello World!&#8221;;
<p>在VB.NET中，使用如下代码：
<p>Dim message = &#8220;Hello World!&#8221;
<p>注意，变量message在声明时并没有为其指定任何类型。C#和VB.NET编译器会根据你初始化变量时的值来推断变量的类型（这里为String类型）。
<p>使用类型推断并没有性能上的损失（变量并非后期绑定）。编译器在编译时就判断出了变量的数据类型。
<p>为了支持类型推断，C#引入了一个新的关键字：var。当你希望编译器自行判断变量的数据类型时，就可以使用var类型声明变量。
<p>当你为局部变量提供初始值时才能使用类型推断。例如，下面的代码不会执行（C#）：
<p>var message;
<p>message = &#8220;Hello World!&#8221;;
<p>由于message变量在声明时没有初始化，这段代码将不能通过编译（C#编译器）。
<p>下面的代码在VB.NET中可以执行（但它做的并不是你想要的）：
<p>Dim message
<p>message = &#8220;Hello World!&#8221;
<p>在这种情况下，VB.NET认为message变量为一个Object类型。由于将字符串赋给了变量，在运行时将会把变量的值转换为String类型。从性能角度看，这并不是一个好的做法。
<p><em>注意：VB.NET 9.0中有一个新的Option叫做Option Infer。要想使隐含类型（implicit typing）正确工作，必须激活Option Infer。你可以在代码文件的最顶端加入&#8220;Option Infer On&#8221;来激活该类的Option Infer。</em>
<p>下一节将介绍类型推断与LINQ to SQL的关系。在使用LINQ to SQL时，很多情况下都无法确定变量的类型，因此你需要编译器能够进行推断。
<h4><strong>理解匿名类型</strong></h4>
<p>另一个类似于动态语言中你可能比较熟悉的概念是匿名类型（Anonymous Types）。当你需要创建一个临时类型（type），却并不想创建一个类（class）时，可以使用匿名类型。
<p>下面的代码介绍了如何在C#中创建匿名类型：
<p>var customer = new {FirstName = &#8220;Stephen&#8221;, LastName = &#8220;Walther&#8221;};
<p>在VB.NET中创建同样的匿名类型，可以使用下面的代码：
<p>Dim customer = New With {.FirstName = &#8220;Stephen&#8221;, .LastName = &#8220;Walther&#8221;}
<p>注意，customer变量并没有指定类型（这与JavaScript或VBScript非常类似）。尽管如此，customer仍然具有它的类型，你只是不知道它的名字而已：它是匿名的，理解这一点是十分重要的。
<p>仅仅一行代码，我们既创建了一个新的类，又实例化了它的属性。其简洁性让我感动到内伤。
<p>在使用LINQ to SQL时，匿名类型十分有用。因为你会发现你经常需要实时地（on the fly）创建一些新类型。例如，当执行一个查询时，你也许希望返回一个类，来代表一些数据库字段的集合。你将需要创建一个包含这些字段的临时类。
<h4><strong>理解泛型</strong></h4>
<p>是的，我知道泛型（Generics）并不是.NET 3.5的新特性。但是，它对LINQ to SQL来说是相当重要的部分，值得我们花点篇幅来回顾。
<p>注意：
<p>要使用泛型，你需要引入System.Collections.Generic命名空间。
<p>我使用泛型的绝大多数情况，是由于泛型集合。例如，如果想描述一个字符串列表，你可以这样声明（C#）：
<p>List&lt;string&gt; stuffToBuy = new List&lt;string&gt;();
<p>stuffToBuy.Add(&#8220;socks&#8221;);
<p>stuffToBuy.Add(&#8220;beer&#8221;);
<p>stuffToBuy.Add(&#8220;cigars&#8221;);
<p>使用VB.NET，则这样声明：
<p>Dim stuffToBuy As New List(Of String)
<p>stuffToBuy.Add(&#8220;socks&#8221;)
<p>stuffToBuy.Add(&#8220;beer&#8221;)
<p>stuffToBuy.Add(&#8220;cigars&#8221;)
<p>现在，利用集合初始化器，你可以仅用一行代码就声明一个强类型的字符串列表（C#）：
<p>List&lt;string&gt; stuffToBuy2 = new List&lt;string&gt; {&#8220;socks&#8221;, &#8220;beer&#8221;, &#8220;cigars&#8221;};
<p><em>注意：VB.NET并不支持集合或数组初始化器。</em>
<p>List类是泛型类，因为在声明的时候指定了它要包含的对象的类型。C#中，要在尖括号之间（&lt; &gt;）指定类型，而在VB.NET中要使用Of关键字。在上例中，我们创建了一个包含字符串的List类。同样地 ，我们也可以创建包含整型或其他自定义类型（如Product和Customer类，分别代表产品和顾客）的List类。
<p>因为泛型是强类型的，因此泛型集合（如List）优于非泛型集合（如ArrayList）。ArrayList将所有对象都保存为object，而泛型将所有对象保存为它们特定的类型。当从ArrayList中取出一个对象时，在使用该对象前你必须将其转换为特定类型。而从泛型中取出对象则不需要这种转换。
<p>泛型并不仅仅局限于集合。你可以创建泛型方法、泛型类以及泛型接口。
<p>例如，当使用ADO.NET时，我喜欢将data reader转换为强类型的List集合。如Listing 18.4所示，GetListFromCommand()方法包含一个command对象，执行该对象，然后自动生成一个强类型的List。
<p>代码清单 18-4 LanguageChanges\App_Code\GenericMethods.cs
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> System.Data.SqlClient;
<span class="kwrd">public</span> <span class="kwrd">class</span> GenericMethods
{
<span class="kwrd">public</span> <span class="kwrd">static</span> List&lt;T&gt; GetListFromCommand&lt;T&gt;(SqlCommand command)
<span class="kwrd">where</span> T: ICreatable, <span class="kwrd">new</span>()
{
List&lt;T&gt; results = <span class="kwrd">new</span> List&lt;T&gt;();
<span class="kwrd">using</span> (command.Connection)
{
command.Connection.Open();
SqlDataReader reader = command.ExecuteReader();
<span class="kwrd">while</span> (reader.Read())
{
T newThing = <span class="kwrd">new</span> T();
newThing.Create(reader);
results.Add(newThing);
}
}
<span class="kwrd">return</span> results;
}
}
<span class="kwrd">public</span> <span class="kwrd">interface</span> ICreatable
{
<span class="kwrd">void</span> Create(SqlDataReader reader);
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>代码清单18-4中的GetListFromCommand()方法接收一个SqlCommand对象并且返回一个泛型List&lt;T&gt;。where子句用来约束泛型类型。泛型约束使得类型T必须实现ICreatable接口并且可以通过new实例化（准确的意思应为，必须包含无参的构造函数。——译者注）。
<p>代码清单18-4中同样定义了ICreatable接口，它要求类实现Create()方法。
<p>既然我们创建了可以将data reader 转换为强类型的list的泛型方法，那么我们就可以用它处理任何实现了ICreatable接口的类，如代码清单18-5中的Movie类。
<p>代码清单 18-5 Movie.cs
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Data.SqlClient;
<span class="kwrd">public</span> <span class="kwrd">class</span> Movie : ICreatable
{
<span class="kwrd">public</span> <span class="kwrd">int</span> Id { get; set; }
<span class="kwrd">public</span> <span class="kwrd">string</span> Title { get; set; }
<span class="kwrd">public</span> <span class="kwrd">void</span> Create(SqlDataReader reader)
{
Id = (<span class="kwrd">int</span>)reader[&#8220;Id&#8221;];
Title = (<span class="kwrd">string</span>)reader[&#8220;Title&#8221;];
}
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>你可以通过下面的方法调用GetListFromCommand()方法（随书CD中的ShowGenericMethods.aspx页面使用了该代码）：
<pre class="csharpcode"><span class="kwrd">string</span> conString = WebConfigurationManager.ConnectionStrings[&#8220;con&#8221;].ConnectionString;
SqlConnection con = <span class="kwrd">new</span> SqlConnection(conString);
SqlCommand cmd = <span class="kwrd">new</span> SqlCommand(&#8220;SELECT Id, Title FROM Movie&#8221;, con);
List&lt;Movie&gt; movies = GenericMethods.GetListFromCommand&lt;Movie&gt;(cmd);</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>在这里，泛型的出色之处在于，你不必为每个类型编写相同的代码将data reader 转换为泛型List。你只编写了一个泛型方法GetListFromCommand()，却可以用该方法转换任何复合泛型约束的类型。
<p>理解泛型的正确方法是理解代码模板。你可以使用泛型来定义某一代码模式，而将一个特定的类应用与该模式中。
<h4><strong>理解Lambda表达式</strong></h4>
<p>Lambda表达式是.NET Framework 3.5引入的另一个新特性，它提供了一种极其简洁的定义方法的方式。
<p>假设你希望将Click事件处理器正确地绑定到button控件，代码清单18-6所示为其中一种方法。
<p>代码清单 18-6 LanguageChanges\NormalMethod.aspx
<pre class="csharpcode"><span class="asp">&lt;%@ Page Language=&#8221;C#&#8221; %&gt;</span>
<span class="kwrd">&lt;!</span><span class="html">DOCTYPE</span> <span class="attr">html</span> <span class="attr">PUBLIC</span> &#8220;<span class="attr">-</span>//<span class="attr">W3C</span>//<span class="attr">DTD</span> <span class="attr">XHTML</span> <span class="attr">1</span>.<span class="attr">0</span> <span class="attr">Transitional</span>//<span class="attr">EN</span>&#8221;
&#8220;<span class="attr">http:</span>//<span class="attr">www</span>.<span class="attr">w3</span>.<span class="attr">org</span>/<span class="attr">TR</span>/<span class="attr">xhtml1</span>/<span class="attr">DTD</span>/<span class="attr">xhtml1-transitional</span>.<span class="attr">dtd</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">script</span> <span class="attr">runat</span>=&#8221;<span class="attr">server</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">void</span> Page_Init()
{
btn.Click += <span class="kwrd">new</span> EventHandler(btn_Click);
}
<span class="kwrd">void</span> btn_Click(<span class="kwrd">object</span> sender, EventArgs e)
{
lblResult.Text = DateTime.Now.ToString();
}
<span class="kwrd">&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">html</span> <span class="attr">xmlns</span>=&#8221;<span class="attr">http:</span>//<span class="attr">www</span>.<span class="attr">w3</span>.<span class="attr">org</span>/<span class="attr">1999</span>/<span class="attr">xhtml</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">head</span> <span class="attr">runat</span>=&#8221;<span class="attr">server</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">title</span><span class="kwrd">&gt;</span>Normal Method<span class="kwrd">&lt;/</span><span class="html">title</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">head</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">body</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">form</span> <span class="attr">id</span>=&#8221;<span class="attr">form1</span>&#8221; <span class="attr">runat</span>=&#8221;<span class="attr">server</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">div</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:Button</span> <span class="attr">id</span>=&#8221;<span class="attr">btn</span>&#8221; <span class="attr">Text</span>=&#8221;<span class="attr">Go</span>!&#8221; <span class="attr">Runat</span>=&#8221;<span class="attr">server</span>&#8221; <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:Label</span> <span class="attr">id</span>=&#8221;<span class="attr">lblResult</span>&#8221;  <span class="attr">Runat</span>=&#8221;<span class="attr">server</span>&#8221; <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">form</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">body</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">html</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>在代码清单18-6中，Page_Init()方法将btn_Click()方法绑定到Button的Click事件。当点击按钮时，执行btn_Click()方法，显示当前日期和时间。这没什么特别之处。
<p>.NET Framework 2.0引入了匿名方法的概念，其好处是可以声明内联方法。例如，代码清单18-7的功能与上例相同，所不同的是使用了匿名方法来处理Button的Click事件。
<p>代码清单 18-7 LanguageChanges\AnonymousMethod.aspx
<pre class="csharpcode"><span class="asp">&lt;%@ Page Language=&#8221;C#&#8221; %&gt;</span>
<span class="kwrd">&lt;!</span><span class="html">DOCTYPE</span> <span class="attr">html</span> <span class="attr">PUBLIC</span> &#8220;<span class="attr">-</span>//<span class="attr">W3C</span>//<span class="attr">DTD</span> <span class="attr">XHTML</span> <span class="attr">1</span>.<span class="attr">0</span> <span class="attr">Transitional</span>//<span class="attr">EN</span>&#8221;
&#8220;<span class="attr">http:</span>//<span class="attr">www</span>.<span class="attr">w3</span>.<span class="attr">org</span>/<span class="attr">TR</span>/<span class="attr">xhtml1</span>/<span class="attr">DTD</span>/<span class="attr">xhtml1-transitional</span>.<span class="attr">dtd</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">script</span> <span class="attr">runat</span>=&#8221;<span class="attr">server</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">void</span> Page_Init()
{
btn.Click += <span class="kwrd">delegate</span>(<span class="kwrd">object</span> sender, EventArgs e)
{
lblResult.Text = DateTime.Now.ToString();
};
}
<span class="kwrd">&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">html</span> <span class="attr">xmlns</span>=&#8221;<span class="attr">http:</span>//<span class="attr">www</span>.<span class="attr">w3</span>.<span class="attr">org</span>/<span class="attr">1999</span>/<span class="attr">xhtml</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">head</span> <span class="attr">id</span>=&#8221;<span class="attr">Head1</span>&#8221; <span class="attr">runat</span>=&#8221;<span class="attr">server</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">title</span><span class="kwrd">&gt;</span>Anonymous Method<span class="kwrd">&lt;/</span><span class="html">title</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">head</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">body</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">form</span> <span class="attr">id</span>=&#8221;<span class="attr">form1</span>&#8221; <span class="attr">runat</span>=&#8221;<span class="attr">server</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">div</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:Button</span> <span class="attr">id</span>=&#8221;<span class="attr">btn</span>&#8221;<span class="attr">Text</span>=&#8221;<span class="attr">Go</span>!&#8221;<span class="attr">Runat</span>=&#8221;<span class="attr">server</span>&#8221; <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:Label</span> <span class="attr">id</span>=&#8221;<span class="attr">lblResult</span>&#8221;<span class="attr">Runat</span>=&#8221;<span class="attr">server</span>&#8221; <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">form</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">body</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">html</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>在代码清单18-7中，处理Click事件的方法是在Page_Init()方法之中声明的。
<p><em>注意：VB.NET并不支持匿名方法，但它支持Lambda表达式，所以VB.NET使用者请不要跳过。</em>
<p>Lambda表达式将匿名方法的概念更进一步，它将声明一个方法所必需的语法数量降到了最低。代码清单18-8使用了Lambda表达式，它功能与以上两个例子相同。
<p>代码清单 18-8 LanguageChanges\LambdaExpression.aspx
<pre class="csharpcode"><span class="asp">&lt;%@ Page Language=&#8221;C#&#8221; %&gt;</span>
<span class="kwrd">&lt;!</span><span class="html">DOCTYPE</span> <span class="attr">html</span> <span class="attr">PUBLIC</span> &#8220;<span class="attr">-</span>//<span class="attr">W3C</span>//<span class="attr">DTD</span> <span class="attr">XHTML</span> <span class="attr">1</span>.<span class="attr">0</span> <span class="attr">Transitional</span>//<span class="attr">EN</span>&#8221;
&#8220;<span class="attr">http:</span>//<span class="attr">www</span>.<span class="attr">w3</span>.<span class="attr">org</span>/<span class="attr">TR</span>/<span class="attr">xhtml1</span>/<span class="attr">DTD</span>/<span class="attr">xhtml1-transitional</span>.<span class="attr">dtd</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">script</span> <span class="attr">runat</span>=&#8221;<span class="attr">server</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">void</span> Page_Init()
{
btn.Click += (sender, e) =&gt; lblResult.Text = DateTime.Now.ToString();
}
<span class="kwrd">&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">html</span> <span class="attr">xmlns</span>=&#8221;<span class="attr">http:</span>//<span class="attr">www</span>.<span class="attr">w3</span>.<span class="attr">org</span>/<span class="attr">1999</span>/<span class="attr">xhtml</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">head</span> <span class="attr">id</span>=&#8221;<span class="attr">Head1</span>&#8221; <span class="attr">runat</span>=&#8221;<span class="attr">server</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">title</span><span class="kwrd">&gt;</span>Lambda Expressions<span class="kwrd">&lt;/</span><span class="html">title</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">head</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">body</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">form</span> <span class="attr">id</span>=&#8221;<span class="attr">form1</span>&#8221; <span class="attr">runat</span>=&#8221;<span class="attr">server</span>&#8221;<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">div</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:Button</span> <span class="attr">id</span>=&#8221;<span class="attr">btn</span>&#8221;<span class="attr">Text</span>=&#8221;<span class="attr">Go</span>!&#8221;<span class="attr">Runat</span>=&#8221;<span class="attr">server</span>&#8221; <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:Label</span> <span class="attr">id</span>=&#8221;<span class="attr">lblResult</span>&#8221;<span class="attr">Runat</span>=&#8221;<span class="attr">server</span>&#8221; <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">form</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">body</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">html</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>代码清单18-8中的Lambda表达式如下，
<p>(sender, e) =&gt; lblResult.Text = DateTime.Now.ToString();
<p>这仅仅是编写方法的简洁方式。Lambda表达式使用=&gt;操作符（goes into操作符）来分隔方法的参数列表和方法体。编译器（通常）可以推断出参数的数据类型。尽管如此，如果你愿意，还是可以像下面的代码那样指明参数类型，
<p>(object sender, EventArgs e) =&gt; lblResult.Text = DateTime.Now.ToString();
<p>有必要提一下，当方法只有一个参数时，圆括号是可选的。因此，Lambda表达式可以非常简洁。
<p>Visual Basic也支持Lambda表达式，但多了一些限制。Visual Basic中的Lambda表达式中只能包含表达式，不能包含语句。
<p>VB中创建Lambda表达式的语法如下，
<p>Dim AddNumbers = Function(x, y) x + y
<p>Response.Write(AddNumbers(5, 6))
<p>第一条语句创建了一个名为AddNumbers的变量，这即为一个Lambda表达式。VB语法Function(x, y) x + y相当于C#语法(x, y) =&gt; x + y。第二条语句使用两个参数调用Lambda表达式。
<h4><strong>理解扩展方法</strong></h4>
<p>扩展方法的概念对于使用过JavaScript（考虑prototype）的人来说，也应该是非常熟悉的。
<p>使用扩展方法，你可以向一个已有类中添加新的方法。例如，你可以创建任意一个方法，并将它添加到String类中。
<p>由于害怕JavaScript注入攻击，我一直以来都对字符串进行HTML编码。在.NET Framework 2.0中，可以调用静态方法Server.HtmlEncode()来对字符串进行HTML编码，如下，
<p>string evilString = &#8220;&lt;script&gt;alert(&#8216;boom!&#8217;)&lt;&#8221; + &#8220;/script&gt;&#8221;;
<p>ltlMessage.Text = Server.HtmlEncode(evilString);
<p>在这段代码中，调用了Server类中的静态方法HtmlEncode()。如果我们可以向下面这样，直接调用字符串的HtmlEncode()方法，岂不妙哉
<p>string evilString = &#8220;&lt;script&gt;alert(&#8216;boom!&#8217;)&lt;&#8221; + &#8220;/script&gt;&#8221;;
<p>ltlMessage.Text = evilString.HtmlEncode();
<p>使用扩展方法，就可以这么做。我们可以向喜欢的类中添加任何方法。创建扩展方法，首先要创建一个静态类，并创建一个第一个参数为特殊参数的静态方法。代码清单18-9向String类中添加HtmlEncode()方法，以此描述了如何创建扩展方法。
<p>代码清单 18-9 LanguageChanges\MyExtensions.vb<a href="#_ftn2_7527" name="_ftnref2_7527">[2]</a>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> MyExtensions
{
<span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">string</span> HtmlEncode(<span class="kwrd">this</span> <span class="kwrd">string</span> str)
{
<span class="kwrd">return</span> System.Web.HttpUtility.HtmlEncode(str);
}
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>注意，HtmlEncode()方法中仅有的参数前面多了关键字this。这样的参数指明了扩展方法所应用的类型。
<p>在VB.NET中创建扩展方法与在C#中极为类似。代码清单18-10中的HtmlEncode()方法与上面的功能相同。
<p>代码清单 18-10 LanguageChanges\MyExtensions.cs<a href="#_ftn3_7527" name="_ftnref3_7527">[3]</a>
<pre class="csharpcode"><span class="kwrd">Imports</span> System.Runtime.CompilerServices
<span class="kwrd">Public</span> <span class="kwrd">Module</span> MyExtensions
&lt;Extension()&gt; _
<span class="kwrd">Public</span> <span class="kwrd">Function</span> HtmlEncode(<span class="kwrd">ByVal</span> str <span class="kwrd">As</span> <span class="kwrd">String</span>) <span class="kwrd">As</span> <span class="kwrd">String</span>
<span class="kwrd">Return</span> System.Web.HttpUtility.HtmlEncode(str)
<span class="kwrd">End</span> <span class="kwrd">Function</span>
<span class="kwrd">End</span> Module</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>当使用VB.NET时，必须将扩展方法声明在一个module中。另外，还必须标记为System.Runtime.CompilerServices.Extension属性。
<h4><strong>理解LINQ</strong></h4>
<p>终于，我们要讨论最后一个话题LINQ了，在这之后我们就可以开始研究本章的真正内容——LINQ to SQL了。
<p>LINQ是Language Integrated Query的简称，它由C#和VB.NET的一系列新特性组成，这些特性允许我们执行查询。LINQ使得SQL查询就像C#或VB.NET的语法一样简单。
<p>一个简单的LINQ查询示例如下，
<p>var words = new List&lt;string&gt; {&#8220;zephyr&#8221;, &#8220;apple&#8221;, &#8220;azure&#8221;};
<p>var results = from w in words
<p>where w.Contains(&#8220;z&#8221;)
<p>select w;
<p>第一条语句创建了一个泛型列表words，它包含三个字符串。第二条语句就是LINQ查询。
<p>LINQ查询及其像反向的SQL语句。它从列表中获得所有的包含字母z的单词。执行该查询，results变量将包含一下两个单词：
<p>zephyr
<p>azure
<p>你可以对所有实现了IEnumerable&lt;T&gt;接口的对象执行标准的LINQ查询。这些实现了该接口的对象称为sequence。常用的sequence均为泛型List类或标准Array类（因此任何可以存入数组中的类，都可以使用LINQ进行查询）。
<p>C#语言提供了以下子句，供我们在查询中使用：
<ul>
    <li>from——指定数据源以及用来迭代数据源的变量（范围变量）。</li>
    <li>where——过滤查询的结果。</li>
    <li>select——指定查询结果中的项。</li>
    <li>group——通过某一关键字，对相关的值进行聚合。</li>
    <li>into——存储聚合中的结果，或连接到一个临时变量。</li>
    <li>orderby——将查询结果按升序或降序进行排序。</li>
    <li>join——通过一个关键字，对两个数据源进行连接。</li>
    <li>let——创建一个临时变量，来存储子查询的结果。</li>
</ul>
<p>创建一个LINQ查询，类似于创建一个反向的SQL查询。LINQ查询以一个from子句开始，它指定了数据的位置。然后，指定where子句来过滤数据。最后，指定用来表示数据的select子句（决定你要返回的对象和属性）。
<p>在内部，标准LINQ查询被翻译成调用System.Linq.Enumerable类的方法。Enumerable类包含了一些扩展方法，这些扩展方法可以应用到任何实现了IEnumerable&lt;T&gt;接口的类中。
<p>因此，查询
<p>var results = from w in words
<p>where w.Contains(&#8220;z&#8221;)
<p>select w;
<p>将被C#编译器翻译成下面的查询
<p>var results = words.Where( w =&gt; w.Contains(&#8220;z&#8221;) ).Select( w =&gt; w );
<p>第一个查询使用了查询语法（query syntax），第二个查询使用了方法语法（method syntax）。这两种查询是相同的。
<p>注意，使用方法语法的查询在Where()和Select()方法中允许使用Lambda表达式。Where()方法中的Lambda表达式用来过滤数据，只返回包含字母z的单词。Select()方法指明要返回的对象和属性。如果我们将Lambda表达式w=&gt;w.Length传递给Select()方法，该查询将返回每个单词的长度，而不是单词本身。
<p>在创建LINQ查询时，使用查询语法还是方法语法纯粹属于个人偏好。查询语法属于语言的特性（C#或VB.NET），方法语法和语言无关。
<p>我发现我使用方法语法的时候更多一些，因为查询语法不过是方法语法的子集。也就是说，使用方法语法可以做更多的事情。然而在某些情况下，使用方法语法编写查询会显得有些冗长。例如，使用查询语法编写LINQ to SQL左外连接，要比使用方法语法简单得多。
<p>最后，选择方法语法还是查询语法其实并不重要，因为所有的查询语法语句都将被编译器翻译成方法语法。在使用标准LINQ时，这些调用的方法都存在与Enumerable类中。
<p>在SDK文档中查找System.Linq.Enumerable类可以浏览Enumerable支持的全部方法。这里列举了一些有趣且实用的方法，
<ul>
    <li>Aggregate()——对序列中的每一项执行同一个函数。</li>
    <li>Average()——返回序列中每一项的平均值。</li>
    <li>Count()——返回序列的总项数。</li>
    <li>Distinct()——返回序列中不同的项。</li>
    <li>Max()——返回序列中的最大值。</li>
    <li>Min()——返回序列中的最小值。</li>
    <li>Select()——返回序列中的某些项或属性。</li>
    <li>Single()——返回序列中的某个单一值。</li>
    <li>Skip()——跳过序列中指定数目的项并返回剩下的元素。</li>
    <li>Take()——返回序列中指定数目的元素</li>
    <li>Where()——过滤序列中的元素。</li>
</ul>
<p>本节我们讨论了标准LINQ（也叫LINQ to Objects）。LINQ使用了Provider Model，它有很多不同的实现，包括LINQ to SQL、LINQ to XML、LINQ over DataSets以及LINQ to Entities。LINQ也有很多第三方实现，包括LINQ to NHibernate和LINQ to SharePoint。这些不同的实现可以用来查询不同的数据源，如XML文件、SharePoint列表等等。
<p>在本章，我们仅讨论LINQ to SQL，它是微软专门为操作数据库数据而设计的官方版本。下面就让我们开始吧。</p>
<p>&nbsp;</p>
<img src ="http://www.cnblogs.com/kirinboy/aggbug/1266986.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42116/" target="_blank">[新闻]消息称MySQL创始人已向Sun提交辞呈</a>]]></description></item><item><title>ORA-01861: 文字与格式字符串不匹配</title><link>http://www.cnblogs.com/kirinboy/archive/2008/05/05/1183004.html</link><dc:creator>麒麟.NET</dc:creator><author>麒麟.NET</author><pubDate>Mon, 05 May 2008 03:16:00 GMT</pubDate><guid>http://www.cnblogs.com/kirinboy/archive/2008/05/05/1183004.html</guid><wfw:comment>http://www.cnblogs.com/kirinboy/comments/1183004.html</wfw:comment><comments>http://www.cnblogs.com/kirinboy/archive/2008/05/05/1183004.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/kirinboy/comments/commentRss/1183004.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/kirinboy/services/trackbacks/1183004.html</trackback:ping><description><![CDATA[摘要: &nbsp;&nbsp;<a href='http://www.cnblogs.com/kirinboy/archive/2008/05/05/1183004.html'>阅读全文</a><img src ="http://www.cnblogs.com/kirinboy/aggbug/1183004.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42115/" target="_blank">[新闻]谷歌Chrome浏览器即将更换LOGO颜色？</a>]]></description></item><item><title>.NET技术书籍推荐</title><link>http://www.cnblogs.com/kirinboy/archive/2008/03/25/dotNet_Books_Recommend.html</link><dc:creator>麒麟.NET</dc:creator><author>麒麟.NET</author><pubDate>Tue, 25 Mar 2008 08:48:00 GMT</pubDate><guid>http://www.cnblogs.com/kirinboy/archive/2008/03/25/dotNet_Books_Recommend.html</guid><wfw:comment>http://www.cnblogs.com/kirinboy/comments/1121536.html</wfw:comment><comments>http://www.cnblogs.com/kirinboy/archive/2008/03/25/dotNet_Books_Recommend.html#Feedback</comments><slash:comments>42</slash:comments><wfw:commentRss>http://www.cnblogs.com/kirinboy/comments/commentRss/1121536.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/kirinboy/services/trackbacks/1121536.html</trackback:ping><description><![CDATA[摘要: 今天看到dudu号召大家推荐对自己最有帮助的技术图书，在下不才，几年间看过的书籍屈指可数，但有幸的是，所看的书都是经典中的经典。借此post向大家推荐一下。因为都是经典书，所以没什么新意，其他人推荐的也不外乎这几本。&nbsp;&nbsp;<a href='http://www.cnblogs.com/kirinboy/archive/2008/03/25/dotNet_Books_Recommend.html'>阅读全文</a><img src ="http://www.cnblogs.com/kirinboy/aggbug/1121536.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42101/" target="_blank">[新闻]淘宝网合并阿里妈妈 专家称阿里巴巴或有新战略</a>]]></description></item><item><title>【翻译】Building a Simple Blog Engine with ASP.NET MVC and LINQ - Part 3</title><link>http://www.cnblogs.com/kirinboy/archive/2008/03/24/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_3.html</link><dc:creator>麒麟.NET</dc:creator><author>麒麟.NET</author><pubDate>Mon, 24 Mar 2008 08:21:00 GMT</pubDate><guid>http://www.cnblogs.com/kirinboy/archive/2008/03/24/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_3.html</guid><wfw:comment>http://www.cnblogs.com/kirinboy/comments/1119913.html</wfw:comment><comments>http://www.cnblogs.com/kirinboy/archive/2008/03/24/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_3.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnblogs.com/kirinboy/comments/commentRss/1119913.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/kirinboy/services/trackbacks/1119913.html</trackback:ping><description><![CDATA[摘要: 在本系列的第三篇，Keyvan讨论了blog引擎中的数据模型，这些模型从Controller中获得数据并传递到View。他借助截图和代码，向我们展示了数据模型中LINQ方面的相关概念。&nbsp;&nbsp;<a href='http://www.cnblogs.com/kirinboy/archive/2008/03/24/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_3.html'>阅读全文</a><img src ="http://www.cnblogs.com/kirinboy/aggbug/1119913.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42096/" target="_blank">[新闻]微软研究院发布 AutoCollage - 整理并融合照片</a>]]></description></item><item><title>【翻译】Building a Simple Blog Engine with ASP.NET MVC and LINQ - Part 2</title><link>http://www.cnblogs.com/kirinboy/archive/2008/02/01/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_2.html</link><dc:creator>麒麟.NET</dc:creator><author>麒麟.NET</author><pubDate>Fri, 01 Feb 2008 08:12:00 GMT</pubDate><guid>http://www.cnblogs.com/kirinboy/archive/2008/02/01/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_2.html</guid><wfw:comment>http://www.cnblogs.com/kirinboy/comments/1061507.html</wfw:comment><comments>http://www.cnblogs.com/kirinboy/archive/2008/02/01/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_2.html#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://www.cnblogs.com/kirinboy/comments/commentRss/1061507.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/kirinboy/services/trackbacks/1061507.html</trackback:ping><description><![CDATA[摘要: 在该ASP.NET MVC Framework系列文章的第二篇里，Keyvan介绍了如何在ASP.NET MVC中使用Controller。他在Blog系统添加了Controller并讨论了一些细节。首先介绍了URL Routing的概念，然后对Controller类进行深入剖析，最后研究了如何在简单Blog系统中实现Controller。&nbsp;&nbsp;<a href='http://www.cnblogs.com/kirinboy/archive/2008/02/01/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_2.html'>阅读全文</a><img src ="http://www.cnblogs.com/kirinboy/aggbug/1061507.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42100/" target="_blank">[新闻]2008年9月5日科技博客精选</a>]]></description></item><item><title>【翻译】Building a Simple Blog Engine with ASP.NET MVC and LINQ - Part 1</title><link>http://www.cnblogs.com/kirinboy/archive/2008/01/30/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_1.html</link><dc:creator>麒麟.NET</dc:creator><author>麒麟.NET</author><pubDate>Wed, 30 Jan 2008 09:12:00 GMT</pubDate><guid>http://www.cnblogs.com/kirinboy/archive/2008/01/30/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_1.html</guid><wfw:comment>http://www.cnblogs.com/kirinboy/comments/1058990.html</wfw:comment><comments>http://www.cnblogs.com/kirinboy/archive/2008/01/30/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_1.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cnblogs.com/kirinboy/comments/commentRss/1058990.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/kirinboy/services/trackbacks/1058990.html</trackback:ping><description><![CDATA[摘要: 微软发布了ASP.NET 3.5 Extensions的第一个CTP版本，它包含ASP.NET 3.5的一个重要的extensions：ASP.NET MVC Framework。本系列文章拟使用ASP.NET MVC和LINQ建立一个简单的Blog系统，在第一部分，Keyvan介绍了MVC模式、ASP.NET MVC Framework以及简单Blog系统的基本原理。&nbsp;&nbsp;<a href='http://www.cnblogs.com/kirinboy/archive/2008/01/30/Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_1.html'>阅读全文</a><img src ="http://www.cnblogs.com/kirinboy/aggbug/1058990.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42099/" target="_blank">[新闻]SNS网站风靡影响工作效率 公司下令封杀</a>]]></description></item><item><title>2008年要做的十件事</title><link>http://www.cnblogs.com/kirinboy/archive/2008/01/01/TenThingsToDoIn2008.html</link><dc:creator>麒麟.NET</dc:creator><author>麒麟.NET</author><pubDate>Tue, 01 Jan 2008 13:52:00 GMT</pubDate><guid>http://www.cnblogs.com/kirinboy/archive/2008/01/01/TenThingsToDoIn2008.html</guid><wfw:comment>http://www.cnblogs.com/kirinboy/comments/1022489.html</wfw:comment><comments>http://www.cnblogs.com/kirinboy/archive/2008/01/01/TenThingsToDoIn2008.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/kirinboy/comments/commentRss/1022489.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/kirinboy/services/trackbacks/1022489.html</trackback:ping><description><![CDATA[<p>2008<span style="font-family: 宋体">年要做的十件事，排名不分先后：</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">要好好学习</span>Java<span style="font-family: 宋体">，到年底的时候，要对</span>Java<span style="font-family: 宋体">有所入门。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">好好学习</span>SOA<span style="font-family: 宋体">，掌握其思想，探索其精髓。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">继续学习设计模式，能熟练并适时的应用各种设计模式。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt">4.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">抽时间学习</span>.NET3.x<span style="font-family: 宋体">，要对</span>WPF<span style="font-family: 宋体">、</span>Silverlight<span style="font-family: 宋体">、</span>AJAX<span style="font-family: 宋体">、</span>Linq<span style="font-family: 宋体">等有所了解。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt">5.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">通过看英文文章的方式学习英语。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt">6.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">至少看</span>10<span style="font-family: 宋体">本技术书籍，</span>5<span style="font-family: 宋体">本非技术书籍。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt">7.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">多运动，经常参加公司的足球、羽毛球活动，每周坚持上肢、胸、腹以及腿部的肌肉练习。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt">8.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">按时打扫房间，保持整洁的生活环境。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt">9.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">多给父母、岳父母打电话。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt">10.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">尽量满足老婆的每个愿望。<br />
<br />
</span></p>
<img src ="http://www.cnblogs.com/kirinboy/aggbug/1022489.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42098/" target="_blank">[新闻]《孢子》正式发布</a>]]></description></item><item><title>我的2007</title><link>http://www.cnblogs.com/kirinboy/archive/2007/12/27/my2007.html</link><dc:creator>麒麟.NET</dc:creator><author>麒麟.NET</author><pubDate>Thu, 27 Dec 2007 13:25:00 GMT</pubDate><guid>http://www.cnblogs.com/kirinboy/archive/2007/12/27/my2007.html</guid><wfw:comment>http://www.cnblogs.com/kirinboy/comments/1017494.html</wfw:comment><comments>http://www.cnblogs.com/kirinboy/archive/2007/12/27/my2007.html#Feedback</comments><slash:comments>27</slash:comments><wfw:commentRss>http://www.cnblogs.com/kirinboy/comments/commentRss/1017494.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/kirinboy/services/trackbacks/1017494.html</trackback:ping><description><![CDATA[<p>2007<span style="font-family: 宋体">年对我来说，是难以忘怀的一年。因为这一年中发生了太多令我难以忘怀的事。说难以忘怀，也只是我不想忘怀或不该忘怀而已，但我这个人记性极其之差，焉能保证若干年后仍然记得这一切？而今时值年尾，不妨做一汇总，留作日后回味。</span></p>
<p><strong><span style="color: #ff6600; font-family: 宋体">毕业</span></strong></p>
<p><span style="font-family: 宋体">上了快</span>20<span style="font-family: 宋体">年学，终于毕业了。当我拿到毕业证的那一刻，有一种如释重负的感觉。再学下去恐怕整个人都要麻木了。<strong style="color: #3366ff">是时候收拾行囊，开始新的旅途了</strong><span style="color: #3366ff">。</span></span></p>
<p><span style="font-family: 宋体">毕业，总是一个伤感的话题。你会和你一起生活过的人说拜拜，有些人可能这辈子不会再有机会谋面。但这次硕士毕业远没有本科毕业那么死去活来，大家都是微笑着说再见。反而和实验室的兄弟姐妹们分开，倒有些依依不舍。可能由于研究生期间大部分时间是在实验室度过的吧。</span></p>
<p><span style="font-family: 宋体">离开了校园，步入了社会，</span>T<span style="font-family: 宋体">公司是我的第一站。它会是唯一一站吗？</span></p>
<p><strong><span style="color: #ff6600; font-family: 宋体">就业</span></strong></p>
<p>1<span style="font-family: 宋体">月</span>4<span style="font-family: 宋体">日</span><span style="font-family: 宋体">，我来到现在办公的大厦面试。当时的面试官明年就要成为我的项目组长。</span>1<span style="font-family: 宋体">月中旬，我正式与</span>T<span style="font-family: 宋体">公司签约，在这里开始了我的职场之旅。</span></p>
<p><span style="font-family: 宋体">刚到公司的时候经历比较坎坷。我被分配到客户服务部，T公司的客服部不是单纯的和客户打交道，它也承担相当一部分的研发工作。正在使用的各个系统的后期维护都归客服部负责。</span></p>
<p><span style="font-family: 宋体">我先是自己选择进</span>D<span style="font-family: 宋体">科，准备用</span>Fortran<span style="font-family: 宋体">开始主机编程之旅。但第二天就后悔了，这几年来辛辛苦苦努力积攒下来的知识，难道就这么放下了？于是我找领导谈了我的想法，说我更适合去做开放平台。公司的领导还是很人性化的，马上给我转到了</span>S<span style="font-family: 宋体">科，在一个项目组做</span>J2EE<span style="font-family: 宋体">开发。当我正准备搁下</span>.NET<span style="font-family: 宋体">开始投身</span>Java<span style="font-family: 宋体">的时候，又被调到了</span>N<span style="font-family: 宋体">项目组做</span>.NET<span style="font-family: 宋体">了。</span></p>
<p><span style="font-family: 宋体">这个项目组所应用的技术可以说是保罗万象，</span>C++<span style="font-family: 宋体">、</span>VB<span style="font-family: 宋体">、</span>Java<span style="font-family: 宋体">、</span>.NET<span style="font-family: 宋体">&#8230;&#8230;我主要负责开发一些小的桌面程序。在校园里我一直是用</span>.NET1.1<span style="font-family: 宋体">开发</span>Web<span style="font-family: 宋体">，现在是用</span>2.0<span style="font-family: 宋体">开发</span>WinForm<span style="font-family: 宋体">，所以至今</span>ASP.NET2.0<span style="font-family: 宋体">还不是很熟。不过我已经列好了计划，准备在新的一年里学习</span>.NET3.x<span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">然而计划始终赶不上变化。就在这一年即将过去的时候，我接到通知，被调到一个新成立的项目组，做基于</span>J2EE<span style="font-family: 宋体">的</span>SOA<span style="font-family: 宋体">。对于这个全新的领域，我所要学习的内容远比</span>.NET3.x<span style="font-family: 宋体">要多得多。<strong><span style="color: #3366ff"><strong>这是一个很大的挑战，也是一个难得的机遇</strong>。</span></strong>可惜的是，要跟共度了</span>3<span style="font-family: 宋体">年多的老朋友</span>.NET<span style="font-family: 宋体">说再见了。</span></p>
<p><strong><span style="color: #ff6600; font-family: 宋体">成家</span></strong></p>
<p>8<span style="font-family: 宋体">月</span>8<span style="font-family: 宋体">日</span><span style="font-family: 宋体">，我与共度</span>7<span style="font-family: 宋体">年风雨的女友在廊坊市安次区婚姻登记处登记结婚，成为合法夫妻。</span>10<span style="font-family: 宋体">月</span>18<span style="font-family: 宋体">日</span><span style="font-family: 宋体">，我们在廊坊迎宾馆举行了婚礼。当时满堂宾朋，好不热闹。</span></p>
<p><span style="font-family: 宋体">家庭之于一个男人来说，并不仅仅意味着多了一个相濡以沫的女人，更意味着要承担起属于丈夫的那份责任。这一点我做的还很不够。</span></p>
<p><span style="font-family: 宋体">我在北京，妻在廊坊，我们工作日两地分居，双休日短暂小聚。尽管</span>7<span style="font-family: 宋体">年的异地恋情，让我们早已习惯不在一起，但每逢下班后，独自徘徊在空荡荡的房间，面对冰冷的墙壁，孤独与相思一股脑向我袭来的时候，还真有点招架不住。</span></p>
<p><span style="font-family: 宋体">新的一年，我要加倍努力。<strong><span style="color: #3366ff"><strong>也许暂时还无法改变现状，但要使现状朝着被改变的方向大踏步前进</strong>。</span></strong></span></p>
<p><strong><span style="color: #ff6600; font-family: 宋体">买车</span></strong></p>
<p><span style="font-family: 宋体">就在我们结婚的当天，接到了</span>4S<span style="font-family: 宋体">店打来的电话，断货一个月的速腾终于有货了。</span>21<span style="font-family: 宋体">、</span>22<span style="font-family: 宋体">日，我们来到店里，付款、办手续，整整忙活了两天，终于把我们的小腾腾请回了家。</span></p>
<p><span style="font-family: 宋体">接下来的日子里我和老婆对他可以说是关怀备至。又是&#8220;洗澡&#8221;，又是&#8220;抹香香&#8221;，又是&#8220;买衣服&#8221;&#8230;&#8230;</span></p>
<p><span style="font-family: 宋体">我们的小腾主要是老婆开。说实话一开始她开的时候我真是提心吊胆。我虽说技术也不咋地，但是理论水平很高（因为受到很多老司机的指点），坐在车里总爱指指点点，这个弯拐的不好，那个道不应该这么并，一来二去就把老婆给说烦了。可能谁也受不了别人在旁边指指点点吧。<strong><span style="color: #3366ff"><strong>毕竟亲自操作的不是你，你再厉害也无法体会别人当时的心理</strong>。</span></strong></span></p>
<p><span style="font-family: 宋体">现在，老婆早已驾轻就熟，我也早就不再说这说那了。不是因为我刻意忍耐，而是她的水平已经远远在我之上了。</span></p>
<p><strong><span style="color: #ff6600; font-family: 宋体">其他</span></strong></p>
<p><span style="font-family: 宋体">其他方面林林总总有很多，都一句话带过吧。</span></p>
<p>2007<span style="font-family: 宋体">年开始在淘宝疯狂的采购，当然，主要是老婆负责采购的环节，我负责付款和与店主讨价还价的环节。</span></p>
<p>2007<span style="font-family: 宋体">年办了</span>7<span style="font-family: 宋体">张信用卡，办卡的一说有礼品，我就心动了，明年得消几张。</span></p>
<p>2007<span style="font-family: 宋体">年开始买基金了，结果刚买就遇到股市震荡，半年没缓过劲来。</span></p>
<p>2007<span style="font-family: 宋体">年工作以来几乎月月光光，当然因为结婚有很多东西需要购置，多花点就多花点吧。明年得好好理一下财，毕竟你不理睬，财不理你。</span></p>
<p>2007<span style="font-family: 宋体">年还发生了什么呢？记不清了，等以后想起来再补充吧。</span></p>
<p><span style="font-family: 宋体">当我还沉浸在回忆之中时，</span>2007<span style="font-family: 宋体">年已经快要过去了。这一年真的是不平凡的一年，成家、立业，这两个最难攻克的桥头堡已经被我拿下。当然，立业只是刚刚迈出了第一步，以后还有很长很艰苦的路要走；成家也仅仅是个开始，呵护一个家庭远比维护一个程序要难。但是，既然第一步已经迈出去了，还会惧怕以后的艰难险阻吗？</span></p>
<span style="font-size: 10.5pt; color: #3366ff; font-family: 宋体"><strong>我的二零零柒，我将永生铭记。</strong></span> 
<img src ="http://www.cnblogs.com/kirinboy/aggbug/1017494.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42097/" target="_blank">[新闻]微软CFO:仍对收购雅虎搜索业务感兴趣</a>]]></description></item><item><title>类型初始值设定项引发异常</title><link>http://www.cnblogs.com/kirinboy/archive/2007/11/07/951903.html</link><dc:creator>麒麟.NET</dc:creator><author>麒麟.NET</author><pubDate>Wed, 07 Nov 2007 03:04:00 GMT</pubDate><guid>http://www.cnblogs.com/kirinboy/archive/2007/11/07/951903.html</guid><wfw:comment>http://www.cnblogs.com/kirinboy/comments/951903.html</wfw:comment><comments>http://www.cnblogs.com/kirinboy/archive/2007/11/07/951903.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/kirinboy/comments/commentRss/951903.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/kirinboy/services/trackbacks/951903.html</trackback:ping><description><![CDATA[摘要: 上午打开VS编译程序的时候，突然出现了这个运行时错误“类型初始值设定项引发异常”。昨天还没有这个错误呢，今天就突然出现，搞得我一头雾水。上网搜了一下，发现有很多人遇到了这个问题。经过一番折腾解决了这个问题后，发现很多人都没有意识到其症结所在，于是写这个随笔，给大家点启发，也给自己做个备忘。&nbsp;&nbsp;<a href='http://www.cnblogs.com/kirinboy/archive/2007/11/07/951903.html'>阅读全文</a><img src ="http://www.cnblogs.com/kirinboy/aggbug/951903.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42095/" target="_blank">[新闻]SQL Server2008十月亮相 标榜智能数据平台</a>]]></description></item></channel></rss>