本文主要是对语言级集成查询或简称为LINQ做一个介绍,包括LINQ是什么,不是什么,并对它在语言特性方面做一个简短的回顾,然后举一些使用LINQ的实际例子进行说明。

语言级集成查询是什么?

在我过去写的大多数文章中,即使是最早的一篇文章(数据库独立的数据访问),也总是涉及到访问和操纵数据,通常,数据是存储在数据库中的,但也有其他种类访问和操纵数据如数据文件,事件日志,注册表等的方式,查询和操纵数据是许多应用程序通用的部分。

LINQ(经常听到有人发音与link一样)在数据访问方面向前推进了一大步,它是一个编程模型,无论是访问文件、XML、数据库、注册表、事件日志、活动目录,还是第三方如Flickr的数据,都使用统一的方法进行访问,它设计与所有不同形态,不同大小的数据一起工作,允许你在所有这些数据上执行查询,设置和转换。

LINQ不是什么

理解一下LINQ不是什么对于理解它是什么非常有帮助,我最常听见的是人们将LINQ认为是嵌入式SQL,我要说的是,它不是嵌入式SQL,尽管LINQ的语法与SQL语法在某些方面非常相似,但它的确不是嵌入式SQL,而且它也不局限于只能查询数据库,.NET语言大部分都不是自动就支持LINQ的,对常见语言运行时(CLR)不用做修改,修改的是语言和它们的编译器,它需要特定语言的扩展,Visual Basic .NET 9.0和C# 3.0已经集成了对LINQ的支持。

LINQ开启的语言特性

LINQ大量使用了类,此外,对Visual Basic和C#语言也进行了大量的扩充以支持LINQ,最近有许多文章介绍这些新的语言特性,作为LINQ的先兆,下面简要列出一部分LINQ语言特性帮助开启LINQ之路:

◆类型接口:代表不同类型的简写是编译时右边赋值的类型
◆扩展方法:扩展一个现有的值或引用类型而不产生一个新的类型
◆对象初始程序:对象初始化语法产生的等效代码的简写形式
◆匿名类型:不合成方法或类型创建声明
◆Lambda表达式:创建排队方法的简单途径
◆查询表达式:在代码中操作对象时与SQL类似

我确信这些语言特性对于LINQ自身肯定有益,但我还没有亲自找到理由在LINQ之外使用它们。

LINQ风格

在访问和操纵不同数据源方面LINQ有多种风格,后面的清单包括了一些由微软提供的数据域,它们中任何一个将来都可能成为.NET的核心话题:

◆面向对象的LINQ:操纵对象的集合
◆面向数据集的LINQ:使用LINQ操纵数据集
◆面向SQL的LINQ:在自定义类型和数据库表语句集之间建立映射
◆面向实体的LINQ:使用一个概念性的实体数据模型创建一个物理数据库的概念模型
◆面向XML的LINQ:允许查询和操纵XML

LINQ语法介绍

对于那些特别想知道如何组织和格式化代码的人而言,需要花一点时间来熟悉LINQ的语法,如何将其运用到自己的代码中去,对于那些已经听说过LINQ不是嵌入式SQL的人,在使用LINQ时可能需要花点时间来适应。

尽管LINQ不是只能访问数据库,我发现它在帮助人们理解LINQ时的价值,首先是检验SQL语句,然后再在代码中加入LINQ表达式完成同样的事情,下面的SQL语句是基于Microsoft SQL Server的Northwind示例数据库中构建的,这个查询非常简单,列出没有住在Berlin顾客。

  1. SELECT c.CompanyName, c.ContactName, c.City
  2. FROM Customers c
  3. WHERE c.City != 'Berlin'
  4. ORDER BY c.ContactName

现在来看看用LINQ表达式做同样的事情,解剖并理解清除其中的细节,有两种查询语法:查询表达式和方法查询。目前,暂时先考虑查询表达式,下面的查询表达式将从GetCustomers()返回的结果查询IEnumerable类型,找出那些没有居住在Berlin的顾客。对于这个例子,你会认为是GetCustomers方法查询数据库并返回IEnumerable类型的。

  1. var customerNotInBerlin =
  2. from c in GetCustomers()
  3. where c.City != "Berlin"
  4. orderby c.ContactName
  5. select c;

下面的表格概述了LINQ可用的部分选项

Destination

目标

var <变量> =

使用类型推理来赋值

Source

from <项目> in <数据源>

信息源提供一套项目

Filter

过滤器

where <表达式>, distinct

表达式指定选择的标准

Order

排序

order by <表达式>, <表达式> [升序 |降序]

控制结果的排序

Aggregate

合计

count([<表达式>]), sum(<表达式>), min(<表达式>), max(<表达式>), avg(<表达式>)

合计源项目

Projection

投影

select <表达式>

构造输出内容

还有更多的选项和语法变化,这里只是为了向你提供一个入门的介绍。

通过例子测试驱动LINQ

至此,你已经对LINQ有一点背景知识了,下面我们通过一个新的有用的例子来对LINQ进行测试,你已经看到如何使用LINQ从结构类型、文件或时间日志中读取数据。

访问结构类型

你可以使用之前的例子显示语法和查询结构类型,你将会创建一个Custome结构类型,并从Northwind数据库获取一些数据来填充Customer结构类型,你可以选择City不是Berlin的记录,然后在终端显示它们,因为你选择的是Customer对象,所以你可以使用ToString方法来格式化输出,使用逗号分隔显示属性。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. namespace LINQIntro
  6. {
  7. class Customer
  8. {
  9. public string CustomerName { get; set; }
  10. public string ContactName { get; set; }
  11. public string City { get; set; }
  12. public override string ToString()
  13. {
  14. return this.CustomerName + ", " +
  15. this.ContactName + ", " + this.City;
  16. }
  17. }
  18.  
  19. class Program
  20. {
  21. static void Main(string[] args)
  22. {
  23. Program.ShowCustomers();
  24. }
  25.  
  26. public static void ShowCustomers()
  27. {
  28. //使用对象初始化程序建立一列customer
  29. List customers = new List {
  30. new Customer { CustomerName = "Alfreds Futterkiste",
  31. ContactName = "Maria Anders", City = "Berlin"},
  32. new Customer { CustomerName =
  33. "Ana Trujillo Emparedados y helados",
  34. ContactName = "Ana Trujillo",
  35. City = "México D.F."},
  36. new Customer { CustomerName =
  37. "Antonio Moreno Taquería",
  38. ContactName = "Antonio Moreno",
  39. City = "México D.F."},
  40. new Customer { CustomerName = "Around the Horn",
  41. ContactName = "Thomas Hardy",
  42. City = "London"},
  43. new Customer { CustomerName = "Berglunds snabbköp",
  44. ContactName = "Christina Berglund",
  45. City = "Luleå"}};
  46.  
  47. //查询customer列,指定显示字段
  48. var customer =
  49. from c in customers
  50. where c.City != "Berlin"
  51. orderby c.ContactName
  52. select c;
  53.  
  54. //在终端显示选择的记录
  55. foreach (var row in customer)
  56. {
  57. Console.WriteLine(row);
  58. }
  59. Console.ReadLine();
  60. }
  61. }
  62. }

显示一列文件

在这个例子中,将使用LINQ查询一个目录中以某个特定名字开始的文件,重复一篇,我是随机选择的目录和文件名,你可能想要修改查询语句中的目录和文件名以适应你的环境。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. namespace LINQIntro
  6. {
  7. class Program
  8. {
  9. static void Main(string[] args)
  10. {
  11. Program.ShowFiles();
  12. }
  13.  
  14. public static void ShowFiles()
  15. {
  16. //指定特定目录
  17. System.IO.DirectoryInfo dirInfo = new
  18. System.IO.DirectoryInfo(
  19. "C:\\Program Files\\Microsoft Visual Studio 9.0");
  20.  
  21. //找出目录中的文件并选中它
  22. var directoryList =
  23. from f in dirInfo.GetFiles("*.*",
  24. System.IO.SearchOption.AllDirectories)
  25. where f.Name.StartsWith("re")
  26. select f;
  27.  
  28. //在终端显示选中的记录
  29. foreach (var row in directoryList)
  30. {
  31. Console.WriteLine(row);
  32. }
  33. Console.ReadLine();
  34. }
  35. }
  36. }

显示运行中的进程

在这个例子中,使用LINQ列出本地PC上正在运行的进程。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. namespace LINQIntro
  6. {
  7. class Program
  8. {
  9. static void Main(string[] args)
  10. {
  11. Program.ShowProcesses();
  12. }
  13.  
  14. public static void ShowProcesses()
  15. {
  16. //选择进程列表并计划输出
  17. var processes = from p in
  18. System.Diagnostics.Process.GetProcesses()
  19. orderby p.ProcessName
  20. select new {
  21. p.ProcessName, p.Id, p.WorkingSet64,
  22. p.Threads, p.HandleCount };
  23.  
  24. //在终端显示选择的记录
  25. foreach (var row in directoryList)
  26. {
  27. Console.WriteLine(row);
  28. }
  29. Console.ReadLine();
  30. }
  31. }
  32. }

访问应用程序日志文件

在这个例子中,使用LINQ从应用程序日志中获取数据,可以在日志中搜索包含某个特定消息的错误日志,我从我本地计算机的事件日志中随机选了一个错误进行搜索,你可能想要调整查询语句以适应你的本地事件日志,对于那些不相信能用LINQ查询日志的人来说,这个例子向你展示了LINQ的能力和价值。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. namespace LINQIntro
  6. {
  7. class Program
  8. {
  9. static void Main(string[] args)
  10. {
  11. Program.ShowEventLog();
  12. }
  13.  
  14. public static void ShowEventLog()
  15. {
  16. //加入应用程序事件日志
  17. System.Diagnostics.EventLog myLog =
  18. new System.Diagnostics.EventLog();
  19. myLog.Log = "Application";
  20.  
  21. //使用terminated为关键字查询错误记录,你可能想要调整EventLogEntryType和
  22. //消息以适应你本地的事件日志,注意自定义对象是如何形成的。
  23. var logEntries =
  24. from System.Diagnostics.EventLogEntry e in
  25. myLog.Entries
  26. where e.EntryType ==
  27. System.Diagnostics.EventLogEntryType.Error &&
  28. e.Message.Contains("terminated")
  29. select new {
  30. e.Source, e.InstanceId, e.Message,
  31. e.TimeGenerated };
  32.  
  33. //显示选择的记录
  34. foreach (var row in logEntries)
  35. {
  36. Console.WriteLine(row);
  37. }
  38. Console.ReadLine();
  39. }
  40. }

小结

本文对LINQ是什么不是什么做了一个简要的概述,同时,你也看到了LINQ开启了新的语言特性,并通过一些例子对LINQ语法进行了介绍,希望本文给你带来了有用的知识,使你能在将来的工作中更好地运用LINQ。

LINQ——语言级集成查询入门指南(1)的更多相关文章

  1. CI Weekly #21 | iOS 持续集成快速入门指南

    搭建 iOS 持续集成环境要多久?每个 iOSer 都有不同的答案.这次我们整理了 flow.ci 的 iOS 持续集成的相关文档和最佳实践,希望帮你更快地完成构建.更新文档见: flow.ci iO ...

  2. C# - LINQ 语言集成查询

    LINQ(Language Integrated Query) LINQ语言集成查询是一组用于C#语言的扩展.它允许编写C#代码对数据集进行查询,比如查询内存中的对象或查询远程数据库的表.利用linq ...

  3. “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法

    “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> 接口或 IQueryable& ...

  4. C#3.0新增功能09 LINQ 基础01 语言集成查询

    连载目录    [已更新最新开发文章,点击查看详细] 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称. 数据查询历来都表示为简单的字符串,没有编译时类型检查或 Inte ...

  5. LINQ(语言集成查询)

    LINQ,语言集成查询(Language Integrated Query)是一组用于c#和Visual Basic语言的扩展.它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作 ...

  6. C#-WebForm-LinQ(一)-LinQ:语言集成查询(Language Integrated Query)-增删改查、属性扩展

    LinQ-语言集成查询(Language Integrated Query) 高集成化的数据库访问技术 LINQ 2 SQL 实际是将数据库的表映射成程序中的类 会把数据库的表名原封不动的变成类名 数 ...

  7. Microsoft Orleans 之 入门指南

    Microsoft Orleans 在.net用简单方法构建高并发.分布式的大型应用程序框架. 原文:http://dotnet.github.io/orleans/ 在线文档:http://dotn ...

  8. Asp.Net MVC4.0 官方教程 入门指南之二--添加一个控制器

    Asp.Net MVC4.0 官方教程 入门指南之二--添加一个控制器 MVC概念 MVC的含义是 “模型-视图-控制器”.MVC是一个架构良好并且易于测试和易于维护的开发模式.基于MVC模式的应用程 ...

  9. [转] Spark快速入门指南 – Spark安装与基础使用

    [From] https://blog.csdn.net/w405722907/article/details/77943331 Spark快速入门指南 – Spark安装与基础使用 2017年09月 ...

随机推荐

  1. HTML5 INPUT新增属性

    HTML5的input标签新增了很多属性,也是让大家非常兴奋的一件事,用简单的一个属性搞定以前复杂的JS验证.input新增的这些属性,使得html和js的分工更明确了,使用起来十分舒畅.我们先看下i ...

  2. 最初程序员的思维“修炼”之四——Android平台开发的“强制关闭”解决思路

    我和我的朋友参加一个比赛——物联网应用技能大赛,这个大赛所要求的技能有,硬件技术,Android平台开发技术,.NET平台开发技术,所以这是一个团队合作的比赛,基本上没有人能同时掌握这三种技术(在校生 ...

  3. Amazon Kinesis Producer Library 使用记录

    Amazon Kinesis 是一种托管的服务,用于有弹性与扩展性的实时处理大规模的流数据.该服务收集大数据记录流,多个可在 Amazon EC2 实例上运行的数据处理应用程序随后可实时使用此流. 在 ...

  4. nginx自启动脚本

    #!/bin/bash # #Startup script for Nginx - this script starts and stops the nginx daemon # # chkconfi ...

  5. mac OS X下安装Redis及Thinkphp3.1使用Redis

    一.安装Redis 1.安装Homebrew 在终端输入ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/install/maste ...

  6. 植物大战僵尸中文第二版和年度版 游戏分析及delphi源码

    00413184 |. E8 77E30100   |CALL PlantsVs.00431500                  ; 地上的物品00413189 |. 8D7424 10     ...

  7. c# datatable list 相互转换

    /*Converts List To DataTable*/ public static DataTable ToDataTable<TSource>(IList<TSource&g ...

  8. Python开发【第一篇】Python基础之反射

    反射 反射的作用:反射得作用是提高代码可读行. __import__导入模块和import导入模块的区别: __import__导入模块是通过字符串进行导入. import是常用得导入模块方法. 扩展 ...

  9. [转]Linux中find常见用法示例

    Linux中find常见用法示例[转]·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \;find命令的参 ...

  10. linux 标准io笔记

    三种缓冲 1.全缓冲:在缓冲区写满时输出到指定的输出端. 比如对磁盘上的文件进行读写通常是全缓冲的. 2.行缓冲:在遇到'\n'时输出到指定的输出端. 比如标准输入和标准输出就是行缓冲, 回车后就会进 ...