现在的位置: 首页 > 综合 > 正文

Linq系列教程三(入门之查询简介)

2015年07月12日 ⁄ 综合 ⁄ 共 3220字 ⁄ 字号 评论关闭

    上讲中我们了解了一些Linq中要用到的一些新机制,这讲中我们来初步了解下Linq的查询,由于此篇内容比较简单明了,微软的说明很清楚,很容易理解,所以决定讲内容讲直接引用MSDN中的教程(不是人懒啊,看来看去这次内容没什么地方需要重点讲解的!大家别丢鸡蛋啊!)。
    所有 LINQ 查询操作都由以下三个不同的操作组成:
    1.获取数据源。
    2.创建查询。
    3.执行查询。
    下面的示例演示如何用源代码表示查询操作的三个部分。为了方便起见,此示例将一个整数数组用作数据源;但其中涉及的概念同样适用于其他数据源。本主题的其余部分也会引用此示例。

 

class IntroToLINQ
{        
    
static void Main()
    {
        
// The Three Parts of a LINQ Query:
        
//  1. Data source.
        int[] numbers = new int[7] { 0123456 };

        // 2. Query creation.
        
// numQuery is an IEnumerable<int>
        var numQuery =
            from num 
in numbers
            
where (num % 2== 0
            select num;

        // 3. Query execution.
        foreach (int num in numQuery)
        {
            Console.Write(
"{0,1} ", num);
        }
    }
}

 

 

下图显示了完整的查询操作。在 LINQ 中,查询的执行与查询本身截然不同;换句话说,如果只是创建查询变量,则不会检索任何数据。
 
数据源
    在上一个示例中,由于数据源是数组,因此它隐式支持泛型 IEnumerable<(of <(T>)>) 接口。这一事实意味着该数据源可以用 LINQ 进行查询。在 foreach 语句中执行查询,而 foreach 要求使用 IEnumerableIEnumerable<(of <(T>)>)。支持 IEnumerable<(of <(T>)>) 或派生接口(如泛型 IQueryable<(of <(T>)>))的类型称为“可查询类型”。

    可查询类型不需要进行修改或特殊处理就可以用作 LINQ 数据源。如果源数据还没有作为可查询类型出现在内存中,则 LINQ 提供程序必须以此方式表示源数据。例如,LINQ to XML 将 XML 文档加载到可查询的 XElement 类型中:

// Create a data source from an XML document.
// using System.Xml.Linq;
XElement contacts = XElement.Load(@"c:/myContactList.xml")
;
 
     在 LINQ to SQL 中,首先手动或使用 对象关系设计器(O/R 设计器) 在设计时创建对象关系映射。针对这些对象编写查询,然后由 LINQ to SQL 在运行时处理与数据库的通信。在下面的示例中,Customer 表示数据库中的特定表,并且 Table 支持派生自 IEnumerable<(of <(T>)>) 的泛型 IQueryable<(of <(T>)>) 接口。
 
// Create a data source from a SQL Server database.
// using System.Data.Linq;
DataContext db = new DataContext(@"c:/northwind/northwnd.mdf");
 

     有关如何创建特定类型的数据源的更多信息,请参见各种 LINQ 提供程序的文档。但基本规则非常简单:LINQ 数据源是支持泛型 IEnumerable<(of <(T>)>) 接口或从该接口继承的接口的任意对象。
    注意:支持非泛型 IEnumerable 接口的类型(如 ArrayList)也可用作 LINQ 数据源。

查询
    查询指定要从数据源中检索的信息。查询还可以指定在返回这些信息之前如何对其进行排序、分组和结构化。查询存储在查询变量中,并用查询表达式进行初始化。为使编写查询的工作变得更加容易,C# 引入了新的查询语法。

上一个示例中的查询从整数数组中返回所有偶数。该查询表达式包含三个子句:from、where 和 select。(如果您熟悉 SQL,您会注意到这些子句的顺序与 SQL 中的顺序相反。) from 子句指定数据源,where 子句应用筛选器,select 子句指定返回的元素的类型。需要注意的是,在 LINQ 中,查询变量本身不执行任何操作并且不返回任何数据。它只是存储在以后某个时刻执行查询时为生成结果而必需的信息。

查询执行

      延迟执行
      如前所述,查询变量本身只是存储查询命令。实际的查询执行会延迟到在 foreach 语句中循环访问查询变量时发生。此概念称为“延迟执行”,下面的示例对此进行了演示:

//  Query execution. 
foreach (int num in numQuery)
{
    Console.Write(
"{0,1} ", num);
}
    foreach 语句也是检索查询结果的地方。例如,在上一个查询中,迭代变量 num 保存了返回的序列中的每个值(一次保存一个值)。

    由于查询变量本身从不保存查询结果,因此可以根据需要随意执行查询。例如,可以通过一个单独的应用程序持续更新数据库。在应用程序中,可以创建一个检索最新数据的查询,并可以按某一时间间隔反复执行该查询以便每次检索不同的结果。

    强制立即执行
    对一系列源元素执行聚合函数的查询必须首先循环访问这些元素。Count、Max、Average 和 First 就属于此类查询。由于查询本身必须使用 foreach 以便返回结果,因此这些查询在执行时不使用显式 foreach 语句。另外还要注意,这些类型的查询返回单个值,而不是 IEnumerable 集合。下面的查询返回源数组中偶数的计数:

var evenNumQuery = 
    from num 
in numbers
    
where (num % 2== 0
    select num;

int evenNumCount = evenNumQuery.Count();

    若要强制立即执行任意查询并缓存其结果,可以调用 ToList<(of <(TSource>)>) 或 ToArray<(of <(TSource>)>) 方法。
List<int> numQuery2 =
    (from num 
in numbers
     
where (num % 2== 0
     select num).ToList();

// or like this:
// numQuery3 is still an int[]

var numQuery3 
=
    (from num 
in numbers
     
where (num % 2== 0
     select num).ToArray();

    此外,还可以通过在紧跟查询表达式之后的位置放置一个 foreach 循环来强制执行查询。但是,通过调用 ToList 或 ToArray,也可以将所有数据缓存在单个集合对象中。

    今天所演示的是Linq的基本工作方式,朋友们可以试着运行下。如果有什么疑问请发我Email!谢谢大家,俺先撤了。

文章来源:宁波.NET俱乐部
作者:小胡子&Violet

抱歉!评论已关闭.