集成查询语言LINQ 是Visual Studio 2008 和 the .NET Framework version 3.5在数据开发方面一个重大的创新.他支持C#和VisualBasie两种编程语言.
LINQ有以下四方面的优势:
1. 它简化了查询实现的方式。如果你正准备去学习C#或Visual Basic,那首先要从学习写LINQ查询开始。
2. 它有统一的语法,可以查询任何一种数据源。无论是XML 文件档、SQL数据库、DataSet数据集,内存在的集合,本地的或者是远程的数据源,都可用它去实现查询。
3. 它加强了关系形数据和实例对象的联系。它可以做为一强名称工具和设计工具去创建对象和数据间的关联。
4. 它能在程序编译捕捉到异常,缩短项目的开发时间。
LINQ标准操作简单介绍
LINQ标准操作是LINQ综合查询语言模型中的一系列方法。大部分方法都是操作实了IEnumerable(Of T) 接口或 th interface IQueryable(Of T).接口对象的序列。这些操作可以实现查询的聚合、排序、过滤、投影等功能。
LINQ标准操作之间的不同在于它们的执行时间和返加的数据是单个值还是一组序列。返回值为单值的方法(聚合函数Sum,Average)它们将会在调用时立即执行;返回值为一组系列的方法,它们将会依懒于查询语句的执行。
下面看看看简单的例子:对字符串数组进行分组,查询,排序!
class Program
{
static void Main(string[] args)
{
string sentence = "This i a simle LINQ DEMO!";
string[] words = sentence.Split(' ');
var query = words.
GroupBy(w => w.Length, w => w.ToUpper()).
Select(g => new { Length = g.Key, Words = g }).
OrderBy(o => o.Length);
foreach (var obj in query)
{
Console.WriteLine("单词的长度 {0}:", obj.Length);
foreach (string word in obj.Words)
Console.WriteLine(word);
}
Console.Read();
}
}
LINQ查询操作必备三部曲
查询就是一种从数据源获取数据的表达式。这种表达式在不同语言中有不同的定义。不同的语言面向不同的数据源,比如说SQL 是面向关系型数据库,XQuery面向XML。因此,开发员人需要为从新数据源或数据格式中获取数据而要学习不同的查询表达式语法。LINQ定义了统一的语法可从不同数据源或数据格式中获取数据,从而减少了开发员人学习的负担,减少了工作量。在LINQ查询中,不管什么数据源,都可以看做为一个对象。你可以使用同样的代码在XML文件,SQL数据库,ADO。NET 数据集,.NET 集合类型,其它数据源或数据格式中查询和传输数据。
所有LINQ查询操作都必包含以下三方面内容:
1. 获取数据源
2. 创建查询
3. 执行查询
下面那张图展示了LINQ查询操作中基本三部分内容这间的依懒关系。从图中可看出,在执行查询操作中必须有查询语语的存在,否则不能从数据源中获取数据。只有创建了查询,执行操作才会对数据进行迭代式处理。
下面看看怎么用代码实现LINQ查询操作基本的三个方面:
{
// 数据源
int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
// 创建查询
IEnumerable<int> numQuery =
from num in numbers
where (num % 2) == 0
select num;
// 执行查询
foreach (int j in numQuery)
{
Console.Write("{0,1} ", j);
}
Console.Read();
}
数据源
首先回头看看前面讲得LINQ标准操作介绍那部份的内容中,可以知道LINQ大部份操作的对象都是实现了IEnumerable(Of T) 接口或 th interface IQueryable(Of T)的对象序列。看看上面写代码实现示例中数据源所用的数据类型是数组类型,而数组类型默认是支持泛型IEnumerable<(Of <T>)接口。这样才使得LINQ在执行查询操作中可以使用foreach来实现对数据的迭代式访问。通常把支持泛型IEnumerable(Of T)接口或泛型IQueryable(Of T)接口的类型称为查询类型。
数组类型正因为它是查询类型,在做为LINQ查询数据源才不用做任何的加工。但如果数据源是XML文档呢,同样道理,必须把它加工为支持泛型IEnumerable(Of T)接口的对象。在. .NET Framework类中XElement就是属于查询类型 ,因此把XML文档转化成XElement类型对象即可。代码如下:
// 创建XML文件类型的数据源
// using System.Xml.Linq;
XElement contacts = XElement.Load(@"c:"myContactList.xml");
如查数据源是SQL 数据库呢,那你第一部就建立数据和实例间的关联(设计时、人工或者使用O/R Designer)。为实例对象写了查询语句好,LINQ会在运行时保持SQL以实例对象中的交互。下面例子了,Customer类型与数据库中的一个表相对应,Table<Customers> 支持泛型 IQueryable(Of T)接口。
//创建SQL数据库中表为数据源.
// using System.Data.Linq;
DataContext db = new DataContext("c:""northwind""northwnd.mdf");
Table<Customer> Customers = db.GetTable<Customer>();
创建查询
创建查询就是要把所需要的数据从数据源中取回来,并可在数据返回这前对数据进行分组、排序。创建查询,在C#在有新的语法定义。可以用它来创建查询表达式。表达式最少要包含两个子句:select和from子句。
在上面那个从数组中返回偶数的例子代码中,查询表达式中有个子句:from,where和select。从表达式在可以看出它跟SQL查询语句的区表,LINQ查询语句中子句的顺序是颠倒过来编写的,所以别混淆了。在LINQ中,查询表达式保存在变量中。如果查询被设计为返回一组数据时,那么该变最就必须为查询类型变量。很重要的一点就是,该变量没有任保的操作也没有返加的信息,它只是保存了查询表达式的信息。查询表达式的设计员人必须要考虑好一个基本点,那就是表达式执行后必须返回数据。
执行查询
A.立即执行
当查询操作返回值为单个值的方法,调用时它立即执行。比如说返回值为单值的Cont,Max,Average,First方法调用时都会立即执行。它立即执行是因为这样的查询需要准备一个序列做为返回单值的计划。接着上面从数组中返回偶数的例子,现在从中计算它返回偶数的数量,即是返回单值。以下看代码:
int query = (from num in numbers
where (num % 2) == 0
select num).Count();
如果要强制立即执行非返加值为单值的查询操作,可以在查询表达式中调用ToList(Of TSource) or ToArray(Of TSource)方法,如下所示
List<int> query2 =
(from num in numbers
where (num % 2) == 0
select num).ToList();
// or
var query3 =
(from num in numbers
where (num % 2) == 0
select num).ToList();
>
B.延迟执行
以查询操作立即执行相比,延迟执行的查询操作它返回的值为一组数据而非单值。查询操作的执行延迟到foreach迭代循环过程中,经历整个迭代过程。
// Query execution.
foreach (int j in numQuery)
{
Console.Write("{0,1} ", j);
}
在这里,再说明一下查询表达式保存的变量没用任何操作和查询结果。上面语句中可看出,返回的数据都保存在foreach循环中的变最j中。每次查询它只返回一个序列,查询表达式变量从不保存返回结果。这也说明了,无论在什么时候执行返回的结果都是最新版本的数据,不必要担心脏数据在出现。当有几个应用程序共亨一个数据源时,就不必要担心执行LINQ查询获取的数据,另一个应用程序正在修改修数据,所返回的数据是旧的版本了。
结束!
参考:MSDN文档