[C# 基础知识系列]专题十六:Linq介绍

时间:2022-08-31 13:23:45

转自http://www.cnblogs.com/zhili/archive/2012/12/24/Linq.html

本专题概要:

  • Linq是什么
  • 使用Linq的好处在哪里
  • Linq的实际操作例子——使用Linq遍历文件目录
  • 小结

引言:

  终于到了C# 3中最重要特性的介绍了,可以说之前所有介绍的特性都是为了Linq而做准备的,然而要想深入理解Linq并不是这个专题可以介绍完的,所以我打算这个专题将对Linq做一个简单的介绍,对于Linq的深入理解我将会后面单独作为一个系列要和大家分享下。

一、Linq是什么?

Linq也就是Language Integrated Query的缩写,即语言集成查询,是微软在.Net 3.5中提出的一项新技术, Linq主要包含4个组件——Linq to Objects、Linq to XML、Linq to DataSet 和Linq to SQL。在这里不会具体介绍这4个组件的内容,只会给出一个大致的介绍, 下面先看看Linq的一个架构图,希望可以让大家可以对Linq有一个全面的认识:

[C# 基础知识系列]专题十六:Linq介绍

下面简单介绍下四个组件:

  • Linq to SQL 组件——可以查询基于关系数据的数据(微软本身只是实现了对SQL Server的查询,可以对数据库中的数据进行查询,修改,插入,删除,排序等操作
  • Linq to Dataset组件——可以查询DasaSet对象中的数据,并对数据进行增删改查的操作
  • Linq to Objects组件——可以查询IEnumberable 或IEnumberable<T>集合
  • Linq to XML 组件——可以差选和操作XML文件,比Xpath操作XML更加方便

二、使用Linq的好处在哪里

第一部分中说到Linq中包括四个组件,分别是对不同数据进行增删改查的一些操作,然而以前也是有相关技术来对这些数据进行操作,(例如,对数据库的操作,之前有Ado.Net 对其进行支持,对XML的操作,之前也可以XPath来操作XML文件等), 此时应该大家都会有个疑问的——为什么以前都有相关的技术对其进行支持,那我们为什么还需要Linq呢?对于这个疑问答案很简单,Linq 使操作这些数据源更加简单,方便和易于理解,之前的技术操作起来过于繁琐,所以微软也有上进心啊,希望可以做的更好啊,所以就在C# 3中提出了Linq来方便大家操作这些数据源,下面通过对比来说明Linq是如何简单方便:

2.1 查询集合中的数据

之前我们查询集合中的数据一般会使用for或foreach语句来进行查询,而Linq 使用查询表达式来进行查询,Linq 表达式比之前用for或forach的方式更加简洁,比较容易添加筛选条件,下面就具体看看两者方式的比较代码(我们这里假设一个场景——返回集合中序号为偶数的元素)

使用foreach 语句来返回序号为偶数的元素的实现代码如下:

[C# 基础知识系列]专题十六:Linq介绍
static void Main(string[] args)
{
#region Linq to objects 对比
Console.WriteLine("使用老方法来对集合对象查询,查询结果为:");
OldQuery();
Console.WriteLine("使用Linq方法来对集合对象查询,查询结果为:");
LinqQuery();
Console.Read(); #endregion
}
#region Linq to Objects对比 // 使用Linq 和使用Foreach语句的对比 // 1. 使用foreach返回集合中序号为偶数的元素
private static void OldQuery()
{
// 初始化查询的数据
List<string> collection = new List<string>();
for (int i = 0; i < 10; i++)
{
collection.Add("A"+i.ToString());
} // 创建保存查询结果的集合
List<string> queryResults = new List<string>();
foreach (string s in collection)
{
// 获取元素序号
int index = int.Parse(s.Substring(1));
// 查询序号为偶数的元素
if (index % 2 == 0)
{
queryResults.Add(s);
}
} // 输出查询结果
foreach (string s in queryResults)
{
Console.WriteLine(s);
}
} // 2. 使用Linq返回集合中序号为偶数的元素
private static void LinqQuery()
{
// 初始化查询的数据
List<string> collection = new List<string>();
for (int i = 0; i < 10; i++)
{
collection.Add("A" + i.ToString());
} // 创建查询表达式来获得序号为偶数的元素
var queryResults = from s in collection
let index = int.Parse(s.Substring(1))
where index % 2 == 0
select s;
// 输出查询结果
foreach (string s in queryResults)
{
Console.WriteLine(s);
}
}
#endregion
[C# 基础知识系列]专题十六:Linq介绍

从上面的两个方法比较中可以看出使用Linq对集合进行查询时确实简单了许多,并且也容易添加筛选条件(只需要在Where 后面添加额外的筛选条件即可),运行结果当然也是我们期望的,下面也附上下运行结果截图:

[C# 基础知识系列]专题十六:Linq介绍

 2.2 查询XML文件

之前我们大部分都会使用XPath来对XML文件进行查询,然而使用XPath来查询XML文件需要首先知道XML文件的具体结构,而Linq 查询表达式在查询XML数据的时,可以不需要知道XML文件结构,并且编码更加简单,容易添加判断的条件,下面就具体代码来说明使用Linq查询的好处(这里假设一个场景——有一个定义Persons的XML文件,现在我们要求查找出XML文件中Name节点为“李四”的元素):

[C# 基础知识系列]专题十六:Linq介绍
static void Main(string[] args)
{
#region Linq to XML 对比
Console.WriteLine("使用XPath来对XML文件查询,查询结果为:");
OldLinqToXMLQuery();
Console.WriteLine("使用Linq方法来对XML文件查询,查询结果为:");
UsingLinqLinqtoXMLQuery();
Console.ReadKey();
#endregion
} #region Linq to XML 对比 // 初始化XML数据
private static string xmlString =
"<Persons>"+
"<Person Id='1'>"+
"<Name>张三</Name>"+
"<Age>18</Age>"+
"</Person>" +
"<Person Id='2'>"+
"<Name>李四</Name>"+
"<Age>19</Age>"+
"</Person>"+
"<Person Id='3'>" +
"<Name>王五</Name>" +
"<Age>22</Age>" +
"</Person>"+
"</Persons>"; // 使用XPath方式来对XML文件进行查询
private static void OldLinqToXMLQuery()
{
// 导入XML文件
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString); // 创建查询XML文件的XPath
string xPath = "/Persons/Person"; // 查询Person元素
XmlNodeList querynodes = xmlDoc.SelectNodes(xPath);
foreach (XmlNode node in querynodes)
{
// 查询名字为李四的元素
foreach (XmlNode childnode in node.ChildNodes)
{
if (childnode.InnerXml == "李四")
{
Console.WriteLine("姓名为: "+childnode.InnerXml + " Id 为:" + node.Attributes["Id"].Value);
}
}
} } // 使用Linq 来对XML文件进行查询
private static void UsingLinqLinqtoXMLQuery()
{
// 导入XML
XElement xmlDoc = XElement.Parse(xmlString); // 创建查询,获取姓名为“李四”的元素
var queryResults = from element in xmlDoc.Elements("Person")
where element.Element("Name").Value == "李四"
select element; // 输出查询结果
foreach (var xele in queryResults)
{
Console.WriteLine("姓名为: " + xele.Element("Name").Value + " Id 为:" + xele.Attribute("Id").Value);
}
}
#endregion
[C# 基础知识系列]专题十六:Linq介绍

使用XPath方式来查询XML文件时,首先需要知道XML文件的具体结构(代码中需要指定XPath为"/Persons/Person", 这就说明必须知道XML的组成结构了),然而使用Linq方式却不需要知道XML文档结构,并且从代码书写的量上也可以看出使用Linq方式的简洁性,下面附上运行结果截图:

[C# 基础知识系列]专题十六:Linq介绍

对于Linq to SQL 和Linq to DataSet的例子,我这里就不一一给出了,从上面的两个例子已经完全可以说明使用Linq的好处了,下面总结我理解的好处有:

  • Linq 查询表达式使用上更加简单,而且也易于理解(没有接触过Linq的人也可以大致猜出代码的意图是什么的)
  • Linq 提供了更多的功能,我们可以查询、排序、分组、增加和删除等操作数据的大部分功能
  • 可以使用Linq处理多种数据源,也可以为特定的数据源定义自己的Linq实现(这点将会在深入理解Linq中与大家相信介绍)

三、Linq的实际操作例子——使用Linq遍历文件目录

通过前面两部分大家大致可以知道Linq的强大了吧,这部分就具体给出一个例子来看看使用Linq具体可以做些什么事情的? 如果大家做一个文件管理系统的时候,大家都需要遍历文件目录的吧,下面就使用Linq来查找在文件目录中的是否存在特定的文件,具体代码如下:

[C# 基础知识系列]专题十六:Linq介绍
   static void Main(string[] args)
{
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); //FileQuery2(desktop);
if (!string.IsNullOrEmpty(FileQuery()))
{
Console.WriteLine(FileQuery());
}
else
{
Console.WriteLine("电脑桌面上不存在text.txt文件");
}
Console.Read();
}
// 使用Linq查询
// 查询桌面是否存在text.txt文件
private static string FileQuery()
{
string desktopdir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); // 获得指定目录和子目录中的文件名
string[] filenames = Directory.GetFiles(desktopdir, "*.*", SearchOption.AllDirectories);
List<FileInfo> files = new List<FileInfo>();
foreach (var filename in filenames)
{
files.Add(new FileInfo(filename));
} var results = from file in files
where file.Name == "text.txt"
select file; // 输出查询结果
StringBuilder queryResult = new StringBuilder();
foreach (var result in results)
{
queryResult.AppendLine("文件的路径为: " + result.FullName);
} return queryResult.ToString();
} /// <summary>
/// 使用递归来查找文件
/// 查询桌面是否存在text.txt文件
/// </summary>
private static void FileQuery2(string path)
{
// 获得指定目录中的文件(包含子目录)
string[] filenames = Directory.GetFiles(path);
List<FileInfo> files = new List<FileInfo>();
foreach (var filename in filenames)
{
files.Add(new FileInfo(filename));
} var results = from file in files
where file.Name == "text.txt"
select file; // 输出查询结果
StringBuilder queryResult = new StringBuilder();
foreach (var result in results)
{
Console.WriteLine("文件的路径为: " + result.FullName);
} // 获得所有子目录
string[] dirs = Directory.GetDirectories(path);
if (dirs.Length > 0)
{
foreach (string dir in dirs)
{
FileQuery2(dir);
}
}
}
[C# 基础知识系列]专题十六:Linq介绍

运行结果为:

[C# 基础知识系列]专题十六:Linq介绍

我的电脑桌面文件结果为:

 Desttop文件夹
text.txt
mytext文件夹
  text文件夹
text.txt
text.txt 

四、小结

到这里本专题的内容就介绍完了, 本专题主要和大家简单分享了下我对Linq的认识,希望让大家对Linq有个大概的认识,在后面的深入理解Linq系列中将会和大家一起剖析下Linq的实现原理。并且这个专题也是C# 3特性中的最后一个特性的介绍了,在后面一个专题中将带来C# 4中一个最重要的特性——动态类型(dynamic )的引入

专题中的源码: http://files.cnblogs.com/zhili/LinqDemo.zip

[C# 基础知识系列]专题十六:Linq介绍的更多相关文章

  1. &lbrack;C&num;基础知识系列&rsqb;专题十&colon;全面解析可空类型&lbrack;转&rsqb;

    原文链接 主要内容: 1:空合并操作符(?? 操作符) ??操作符也就是"空合并操作符",它代表的意思是两个操作数,如果左边的数不为null时,就返回左边的数,如果左边的数为nul ...

  2. &lbrack;C&num; 基础知识系列&rsqb;专题一:深入解析委托——C&num;中为什么要引入委托

    转自http://www.cnblogs.com/zhili/archive/2012/10/22/Delegate.html 引言: 对于一些刚接触C# 不久的朋友可能会对C#中一些基本特性理解的不 ...

  3. &lbrack;C&num; 基础知识系列&rsqb;专题九&colon; 深入理解泛型可变性

    引言: 在C# 2.0中泛型并不支持可变性的(可变性指的就是协变性和逆变性),我们知道在面向对象的继承中就具有可变性,当方法声明返回类型为Stream,我们可以在实现中返回一个FileStream的类 ...

  4. &lbrack;C&num; 基础知识系列&rsqb;专题三:如何用委托包装多个方法——委托链 (转载)

    引言: 上一专题介绍了下编译器是如何来翻译委托的,从中间语言的角度去看委托,希望可以帮助大家进一步的理解委托,然而之前的介绍都是委托只是封装一个方法,那委托能不能封装多个方法呢?因为生活中经常会听到, ...

  5. &lbrack;C&num; 基础知识系列&rsqb;专题七&colon; 泛型深入理解&lpar;一&rpar; (转载)

    引言: 在上一个专题中介绍了C#2.0 中引入泛型的原因以及有了泛型后所带来的好处,然而上一专题相当于是介绍了泛型的一些基本知识的,对于泛型的性能为什么会比非泛型的性能高却没有给出理由,所以在这个专题 ...

  6. &lbrack;C&num; 基础知识系列&rsqb;专题八&colon; 深入理解泛型&lpar;二&rpar;

    引言: 本专题主要是承接上一个专题要继续介绍泛型的其他内容,这里就不多说了,就直接进入本专题的内容的. 一.类型推断 在我们写泛型代码的时候经常有大量的"<"和"& ...

  7. &lbrack;C&num; 基础知识系列&rsqb;专题四:事件揭秘

    转自http://www.cnblogs.com/zhili/archive/2012/10/27/Event.html 引言: 前面几个专题对委托进行了详细的介绍的,然后我们在编写代码过程中经常会听 ...

  8. &lbrack;C&num; 基础知识系列&rsqb;专题四:事件揭秘 (转载)

    引言: 前面几个专题对委托进行了详细的介绍的,然后我们在编写代码过程中经常会听到“事件”这个概念的,尤其是写UI的时候,当我们点击一个按钮后VS就会自动帮我们生成一些后台的代码,然后我们就只需要在Cl ...

  9. &lbrack;C&num; 基础知识系列&rsqb;专题六&colon;泛型基础篇——为什么引入泛型

    引言: 前面专题主要介绍了C#1中的2个核心特性——委托和事件,然而在C# 2.0中又引入一个很重要的特性,它就是泛型,大家在平常的操作中肯定会经常碰到并使用它,如果你对于它的一些相关特性还不是很了解 ...

随机推荐

  1. WebAPI 2参数绑定方法

    简单类型参数 Example 1: Sending a simple parameter in the Url [RoutePrefix("api/values")] public ...

  2. 求最大边&sol;最小边的比值最小的路径 codevs 1001 舒适的路线

    codevs 1001 舒适的路线 2006年  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description Z小镇是一个景色宜人 ...

  3. &sol;run&sol;systemd&sol;private&colon; No such file or directory

    今天执行consul脚本的时候报错 /run/systemd/private: No such file or directory reboot -f 重启电脑private文件就出现了.

  4. unity 3消 游戏

    3消游戏跟着智能手机流行到现在已经有很长一段时间,unity实现的3消 https://github.com/textcube/match3action 截图如下: 在阅读源码的时候不难发现,Game ...

  5. &lbrack;PR &amp&semi; ML 3&rsqb; &lbrack;Introduction&rsqb; Probability Theory

    虽然学过Machine Learning和Probability今天看着一part的时候还是感觉挺有趣,听惊呆的,尤其是Bayesian Approach.奇怪发中文的笔记就很多人看,英文就没有了,其 ...

  6. 使用Websocket框架之GatewayWorker开发电商平台买家与卖家实时通讯

    前段时间公司提了一个新的需求,在商品的详情页要实现站内买家和商品卖家实时通讯的功能以方便沟通促成交易,要开发此功能当时首先考虑到的就是swoole和workerman了,从网上大概了解了一下关于这两款 ...

  7. 在maven中开发Spring需要的jar依赖

    在maven中开发Spring需要的jar依赖 <properties> <spring.version>4.0.6.RELEASE</spring.version&gt ...

  8. 关于微信分享的一些心得之recommend&period;js&lpar;直接复制就行&rpar;

    // import $ from 'jquery'import Vue from 'vue'export default function (type,title,con,img,url,) {  / ...

  9. 利用jenkins&plus;git自动执行接口测试代码

    事前准备 部署好jenkins.申请一个码云账号.代码同步至码云 1.在码云上新建一个项目,并把代码同步上去 我设置成了私有项目 2.为项目添加部署公钥 因为是私有项目,所以需要添加一个部署公钥,不然 ...

  10. 解决 Ubuntu 14&period;04 图形界面无法正常显示 问题

    参考: ubuntu清除系统缓存的方法 apt-get(四) 每天一个linux命令(33):df 命令 Ubuntu server 12.10 /dev/sda1 disk full 解决 Ubun ...