查看: 5|回复: 0
打印 上一主题 下一主题

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

[复制链接]
  • TA的每日心情
    难过
    2016-3-1 09:50
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    跳转到指定楼层
    楼主
    发表于 2019-9-29 21:50:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    本专题概要:
    • 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有一个全面的认识:
    下面简单介绍下四个组件:
    • Linq to SQL 组件——可以查询基于关系数据的数据(微软本身只是实现了对SQL Server的查询,可以对数据库中的数据进行查询,修改,插入,删除,排序等操作
    • Linq to Dataset组件——可以查询DasaSet对象中的数据,并对数据进行增删改查的操作
    • Linq to Objects组件——可以查询IEnumberable 或IEnumberable集合
    • 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 语句来返回序号为偶数的元素的实现代码如下:
    [url=][/url]
    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[url=][/url]

    从上面的两个方法比较中可以看出使用Linq对集合进行查询时确实简单了许多,并且也容易添加筛选条件(只需要在Where 后面添加额外的筛选条件即可),运行结果当然也是我们期望的,下面也附上下运行结果截图:
    2.2 查询XML文件
    之前我们大部分都会使用XPath来对XML文件进行查询,然而使用XPath来查询XML文件需要首先知道XML文件的具体结构,而Linq 查询表达式在查询XML数据的时,可以不需要知道XML文件结构,并且编码更加简单,容易添加判断的条件,下面就具体代码来说明使用Linq查询的好处(这里假设一个场景——有一个定义Persons的XML文件,现在我们要求查找出XML文件中Name节点为“李四”的元素):
    [url=][/url]
    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 =? ?? ?? ?? ? ""+? ?? ?? ?? ?""+? ?? ?? ?? ?"张三"+? ?? ?? ?? ?"18"+? ?? ?? ?? ?"" +? ?? ?? ?? ?""+? ?? ?? ?? ?"李四"+? ?? ?? ?? ?"19"+? ?? ?? ?? ?""+? ?? ?? ?? ? "" +? ?? ?? ?? ?"王五" +? ?? ?? ?? ?"22" +? ?? ?? ?? ?""+? ?? ?? ?? ?"";? ?? ???// 使用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[url=][/url]

    使用XPath方式来查询XML文件时,首先需要知道XML文件的具体结构(代码中需要指定XPath为"/Persons/Person", 这就说明必须知道XML的组成结构了),然而使用Linq方式却不需要知道XML文档结构,并且从代码书写的量上也可以看出使用Linq方式的简洁性,下面附上运行结果截图:
    对于Linq to SQL 和Linq to DataSet的例子,我这里就不一一给出了,从上面的两个例子已经完全可以说明使用Linq的好处了,下面总结我理解的好处有:
    • Linq 查询表达式使用上更加简单,而且也易于理解(没有接触过Linq的人也可以大致猜出代码的意图是什么的)
    • Linq 提供了更多的功能,我们可以查询、排序、分组、增加和删除等操作数据的大部分功能
    • 可以使用Linq处理多种数据源,也可以为特定的数据源定义自己的Linq实现(这点将会在深入理解Linq中与大家相信介绍)
    三、Linq的实际操作例子——使用Linq遍历文件目录
    通过前面两部分大家大致可以知道Linq的强大了吧,这部分就具体给出一个例子来看看使用Linq具体可以做些什么事情的? 如果大家做一个文件管理系统的时候,大家都需要遍历文件目录的吧,下面就使用Linq来查找在文件目录中的是否存在特定的文件,具体代码如下:
    [url=][/url]
    ? ?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 files = new List();? ?? ?? ?? ?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();? ?? ???}? ?? ???/// ? ?? ???/// 使用递归来查找文件? ?? ???///??查询桌面是否存在text.txt文件? ?? ???/// ? ?? ???private static void FileQuery2(string path)? ?? ???{? ?? ?? ?? ?// 获得指定目录中的文件(包含子目录)? ?? ?? ?? ?string[] filenames = Directory.GetFiles(path);? ?? ?? ?? ?List files = new List();? ?? ?? ?? ?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);? ?? ?? ?? ?? ? }? ?? ?? ?? ?}? ?? ???}[url=][/url]

    运行结果为:
    我的电脑桌面文件结果为:
    Desttop文件夹? ? text.txt? ? mytext文件夹 ? ???text文件夹? ?? ?? ?? ?text.txt? ?? ???text.txt ? ?
    四、小结
    到这里本专题的内容就介绍完了, 本专题主要和大家简单分享了下我对Linq的认识,希望让大家对Linq有个大概的认识,在后面的深入理解Linq系列中将会和大家一起剖析下Linq的实现原理。并且这个专题也是C# 3特性中的最后一个特性的介绍了,在后面一个专题中将带来C# 4中一个最重要的特性——动态类型(dynamic )的引入

    本版积分规则

    Copyright 1999-2019 Beijing Aptech Beida Jade Bird Information Technology Co.,Ltd

    北大bt365官网网址 8IT教育 北京阿博泰克北大bt365官网网址 8信息技术有限公司 版权所有

    京ICP备11045574号-3 京公网安备11010802013845号

    快速回复 返回顶部 返回列表