Linq 学习笔记(二)

来源:互联网 发布:嵌入式算不算人工智能 编辑:程序博客网 时间:2024/05/02 03:03

                   今天简单介绍一下昨天学习中说到的LINQ的三点:数据源,创建查询,执行查询。

                完整的 LINQ 查询操作

这张图可以清晰的解释这这三者之间的关系:LINQ 中,查询的执行与查询本身截然不同;换句话说,如果只是创建查询变量,则不会检索任何数据。

         数据源:

       在上一个示例中,由于数据源是数组,因此它隐式支持泛型 IEnumerable<T> 接口这一事实意味着该数据源可以用 LINQ 进行查询。查询在foreach 语句中执行,因此,foreach 需要IEnumerableIEnumerable<T>。支持IEnumerable<T> 或派生接口 (如泛型IQueryable<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 中,首先手动或使用Object Relational Designer (O/R Designer) 在设计时创建对象关系映射。 针对这些对象编写查询,然后由 LINQ to SQL 在运行时处理与数据库的通信。                         在下面的示例中,Customers 表示数据库中的特定表,并且查询结果的类型IQueryable<T> 派生自IEnumerable<T>。                       

Northwnd db = new Northwnd(@"c:\northwnd.mdf");// Query for customers in London.IQueryable<Customer> custQuery =    from cust in db.Customers    where cust.City == "London"    select cust;

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

    关于查询:

查询指定要从数据源中检索的信息。 查询还可以指定在返回这些信息之前如何对其进行排序、分组和结构化。查询存储在查询变量中,并用查询表达式进行初始化。  为使编写查询的工作变得更加容易,C# 引入了新的查询语法。上一个示例中的查询从整数数组中返回所有偶数。                         该查询表达式包含三个子句:fromwhereselect。      (如果您熟悉 SQL,您会注意到这些子句的顺序与 SQL 中的顺序相反。)from 子句指定数据源,where 子句应用筛选器,select 子句指定返回的元素的类型。

    执行查询

延迟执行          

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

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

foreach  语句也是检索查询结果的地方。 例如,在上一个查询中,迭代变量 num 保存了返回的序列中的每个值(一次保存一个值)。  由于查询变量本身从不保存查询结果,因此可以根据需要随意执行查询。   例如,可以通过一个单独的应用程序持续更新数据库。 在应用程序中,可以创建一个检索最新数据的查询,并可以按某一时间间隔反复执行该查询以便每次检索不同的结果。                           

强制立即执行          

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

var evenNumQuery =     from num in numbers    where (num % 2) == 0    select num;int evenNumCount = evenNumQuery.Count();

若要强制立即执行任意查询并缓存其结果,可以调用ToList<TSource>ToArray<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 循环来强制执行查询。                             但是,通过调用 ToListToArray,也可以将所有数据缓存在单个集合对象中。

 

 

原创粉丝点击