LINQ入门(下篇)

来自森大科技官方博客
http://www.cnsendblog.com/index.php/?p=172
GPS平台、网站建设、软件开发、系统运维,找森大网络科技!
http://cnsendnet.taobao.com

到现在为止你还未触碰LINQ,那进来吧 —— LINQ入门(下篇)

  终于来到下篇了,通过上篇,和中篇,我们了解了linq的基本语句,对应linq我们又了解到lambda表达式,静态扩展方法,以及linq的延迟加载的特性,那么在本篇文章中我们将分享学习一下linq对于我们开发中常用到的对象的操作应用。如果没有阅读过上篇的请点击这里,如果没有阅读中篇的请点击这里

linq to DataSet

  对于做.net 开发的有谁不知道DataSet,DataTable,DataRow,DataColumn这些对象,如果你真的不知道,那好吧建议你到菜市场买2块豆腐撞死算了>_<。也许你会惊讶,哇靠!linq能操作这些?答案是肯定的。那么我们来看看linq是怎么操作的。

  1. 命名空间,如果需要linq操作DataSet,需要以下命名空间

using System.Data;

using System.Linq;

  2. 关键方法 AsEnumerable,该方法为一个静态扩展方法,他将DataTable转换为一个IEnumerable<DataRow>的序列

var dt = new DataTable();
dt.Columns.Add("A", typeof(int));

var newRow1 = dt.NewRow();
var newRow2 = dt.NewRow();

newRow1["A"] = 1;
newRow2["A"] = 2;

dt.Rows.Add(newRow1);
dt.Rows.Add(newRow2);

// 重点看这里
IEnumerable<DataRow> rows = dt.AsEnumerbale();

foreach(row in rows)
    Console.WriteLine(row["A"].ToString());

从这段代码看,并没有什么实质意义,如果这样去遍历datarow就是脱裤子放屁,多此一举。但是这样做的目只有一个为下面的linq操作做铺垫。

  3. linq DataRow 操作,以下举例一些linq特有的常用datarow操作

   Distinct,顾名思义该方法返回的没有重复值的datarow序列

var dt = new DataTable();
dt.Columns.Add("A", typeof(int));

var newRow1 = dt.NewRow();
var newRow2 = dt.NewRow();

newRow1["A"] = 1;
newRow2["A"] = 2;
newRow3["A"] = 2;

dt.Rows.Add(newRow1);
dt.Rows.Add(newRow2);
dt.Rows.Add(newRow3);

// 重点看这里
IEnumerable<DataRow> rows = dt.AsEnumerbale();
// 去重复
IEnumerable<DataRow> distinctRows = rows.Distinct(DataRowComparer.Default);

foreach(var row in distictRows)
    Console.WriteLine(row["A"].ToString());

// 结果
// 1
// 2

注意,这里的 DataRowComparer 是一个静态类,属性 Default 表示返回单一的DataRow实例
   Except, 找到DataRow序列A中在datarow序列B中没有的datarow序列

var dt1 = new DataTable();
dt1.Columns.Add("A", typeof(int));

var dt2 = new DataTable();
dt2.Columns.Add("A", typeof(int));

dt1.Rows.Add(new object[] { 1 });
dt1.Rows.Add(new object[] { 2 });

dt2.Rows.Add(new object[] { 2 });
dt2.Rows.Add(new object[] { 3 });

// 重点看这里
IEnumerable<DataRow> rows1 = dt1.AsEnumerable();
IEnumerable<DataRow> rows2 = dt2.AsEnumerable();

// 获取rows1中在rows2里没有包含的datarow序列
var rows3 = rows1.Except(rows2, DataRowComparer.Default);

foreach (var row in rows3)
    Console.WriteLine(row["A"].ToString());

// 结果
// 1

Intersect, 两个DataRow序列的交集

var dt1 = new DataTable();
dt1.Columns.Add("A", typeof(int));

var dt2 = new DataTable();
dt2.Columns.Add("A", typeof(int));

dt1.Rows.Add(new object[]{1});
dt1.Rows.Add(new object[]{2});

dt2.Rows.Add(new object[]{2});
dt2.Rows.Add(new object[]{3});

// 重点看这里
IEnumerable<DataRow> rows1 = dt1.AsEnumerbale();
IEnumerable<DataRow> rows2 = dt2.AsEnumerbale();

// 获取rows1与rows2共有的datarow序列
rows1.Intersect(row2, DataRowComparer.Default); 

foreach(var row in rows1)
    Console.WriteLine(row["A"].ToString());
// 结果
// 2

Union,合并两个datarow序列

var dt1 = new DataTable();
dt1.Columns.Add("A", typeof(int));

var dt2 = new DataTable();
dt2.Columns.Add("A", typeof(int));

dt1.Rows.Add(new object[] { 1 });
dt1.Rows.Add(new object[] { 2 });

dt2.Rows.Add(new object[] { 2 });
dt2.Rows.Add(new object[] { 3 });

// 重点看这里
IEnumerable<DataRow> rows1 = dt1.AsEnumerable();
IEnumerable<DataRow> rows2 = dt2.AsEnumerable();

// 合并rows1与rows2
var row3 = rows1.Union(rows2, DataRowComparer.Default);

foreach (var row in row3)
    Console.WriteLine(row["A"].ToString());
// 结果
// 1
// 2
// 3

SequenceEqual,判断两个dataorw序列是否相等

var dt1 = new DataTable();
dt1.Columns.Add("A", typeof(int));

var dt2 = new DataTable();
dt2.Columns.Add("A", typeof(int));

dt1.Rows.Add(new object[]{1});
dt1.Rows.Add(new object[]{2});

dt2.Rows.Add(new object[]{2});
dt2.Rows.Add(new object[]{3});

// 重点看这里
IEnumerable<DataRow> rows1 = dt1.AsEnumerbale();
IEnumerable<DataRow> rows2 = dt2.AsEnumerbale();

// 合并rows1与rows2
var equal = rows1.SequenceEqual(row2, DataRowComparer.Default); 

Console.WriteLine(equal.ToString());

// 结果
// false

4. linq DataColumn 操作

  在了解了对datarow的操作后,我们再来了解一下对datacolumn的操作

   Field<T> , 它是一个获取当前行(datarow)的某一列值的静态扩展方法,它具有三种重载参数,类型分别是DataColumn, String, Int,在这里建议大家使用string 类型参数,明确是取哪一列,语句阅读上更流畅。

var dt = new DataTable();
dt.Columns.Add("A", typeof(int));

var newRow1 = dt.NewRow();
var newRow2 = dt.NewRow();

newRow1["A"] = 1;
newRow2["A"] = 2;

dt.Rows.Add(newRow1);
dt.Rows.Add(newRow2);

IEnumerable<DataRow> rows = dt.AsEnumerbale();

// 重点看这里
foreach(var val in rows.Select(e => e.Field<int>("A"))
    Console.WriteLine(val.ToString());

   SetField<T> , 该方法刚好是对当前行某一列进行赋值操作,同样也具有三种重载参数DataColumn, String, Int,在这里建议大家使用string 类型参数,明确是取哪一列,语句阅读上更流畅。

var dt = new DataTable();
dt.Columns.Add("A", typeof(int));

var newRow1 = dt.NewRow();
var newRow2 = dt.NewRow();

newRow1["A"] = 1;
newRow2["A"] = 2;

dt.Rows.Add(newRow1);
dt.Rows.Add(newRow2);

IEnumerable<DataRow> rows = dt.AsEnumerbale();

// 重点看这里
foreach(var row in rows)
    row.SetField<int>("A", row.Field<int>("A")+10);

foreach(var val in rows.Select(e => e.Field<int>("a")))
    Console.WriteLine(val.ToString())

// 结果
// 11
// 12

  5. CopyToDataTable<DataRow>,该方法是将datarow序列组成一个新的DataTable

// 已知一个DataTable
var dt = new DataTable();

// 获取一个DataRow序列
var rows = dt.AsEnumerable();

//经过一系列操作
// ....

//获取一个新的DataTable
var newDt = rows.CopyToDataTable();

至此,我们对linq to DataSet 有了一个基本认识与了解,那么下面我们将了解另一个应用 linq to xml

linq to XML

   在实际应用中,并不需要我们使用linq对xml对象进行操作,因为MS已经提供了封装对xml的linq操作的对象,我们一起来简单的了解下有哪些对象。

  1.命名空间,linq to xml 需要如下命名空间

using System.Linq;

using System.Xml.Linq;

  2. linq to xml 主要类型对象

  XDocument : 表示 XML 文档

  XElement : 表示一个 XML 元素

  XAttribute: 表示一个 XML 特性(节点属性)

  XNamespace: 表示一个 XML 命名空间

  XCData: 表示一个包含 CDATA 的文本节点(注释)

  XDeclaration : 表示一个 XML 声明

// 创建一个XML文档
var xDoc = new XDocument(
    // 定义声明
    new XDeclaration("1.0", "utf-8", "yes"),
        // 添加根节点
        new XElement("root",
            // 添加子节点1,并添加节点属性“name”
            new XElement("item1", new XAttribute("name","属性"), "子节点1"),
            // 添加子节点2,并添加内容注释CDATA
            new XElement("item2", new XCData("注释"))));

// 输出结果
//<?xml version="1.0" encoding="utf-8" standalone="yes"?>
//<root>
//  <item1 name="属性">子节点1</item1>
//  <item2><![CDATA[注释]]></item2>
//</root>

  2. 输出XML文档,当我们创建好一个xml文档对象时,调用该对象的方法 Save 即可,如下:

// 创建一个XML文档
var xDoc = new XDocument(
    // 定义声明
    new XDeclaration("1.0", "utf-8", "yes"),
        // 添加根节点
        new XElement("root",
            // 添加子节点1,并添加节点属性“name”
            new XElement("item1", new XAttribute("name","属性"), "子节点1"),
            // 添加子节点2,并添加内容注释CDATA
            new XElement("item2", new XCData("注释"))));

// 输出XML文档
xDoc.Save("demo.xml");

3. 导入xml文档,如果已知一个XML文本文件,我们需要获取这个xml文本文件XDocment对象时,可以执行改对象方法 Load,该方法具有八种参数重载,参数类型分别是StreamStringTextReaderXmlReader。下面的示例中使用的是 string 类型参数传递

XDocment xDoc = XDocument.Load("demo.xml");

  4. XNode 抽象基类,表示 XML 树中节点的抽象概念(元素、注释、文档类型、处理指令或文本节点),简单理解就是我们可以把XML的内容每一个部分都视为节点,也就是说它是类型的基类,并提供了大量的操作xml方法。

  摘自MSDN:

XNode 是以下类型的抽象公共基类:

  • XComment
  • XContainer
  • XDocumentType
  • XProcessingInstruction
  • XText

XContainer 是以下类型的抽象公共基类:

  • XDocument
  • XElement

派生自 XContainer 的类的对象可以包含子节点。

  5. 常用遍历方法

    DescendantNodes : 按文档顺序返回此文档或元素的子代节点集合。

    Elements : 按文档顺序返回此元素或文档的子元素集合

var xDoc = XDocument.Load("demo.xml");

IEnumerable<XNode>
nodex = xDoc.DescendantNodes();

IEnumerable<XElement>
elems = xDoc.Elements();

  当我们获取到到节点或者元素的序列后就可以对这些对象进行常规的LINQ操作,例如运用前两篇介绍的知识。

  由于篇幅关系,这里就不逐一去讲解每个LINQ TO XMLAPI了,感兴趣的读者可以去msdn查阅System.Xml.Linq命名空间下的操作对象。

  (吐槽)当我写完这篇文章时,自我感觉很枯燥,通篇介绍的都是API封装没有体现出LINQ的新意,想删掉这篇文章的冲动都有,但是一想既然我们要学习LINQ,这些东西还是需要适当了解与接触,所以还是硬着头皮写下来了,如果你能看完整篇文章,那真的非常感谢,感谢你的支持。

  linq to xml 在效率上和 xml 的 xpath 差不了多少,所以在什么情况下怎么使用任君选择,并不需要强制使用的。

  linq to dataset 小数据的时候可以这么干,但是数据量大时候,我建议不要这么干,首先要执行AsEnumberable这样一个耗时的方法划不来,不如直接上foreach遍历。

  最终篇将和大家分享并讨论最受大家所熟知的LINQ TO SQL,还是希望大家给予一点期待吧。

  感谢阅读,如果有说的不对的地方请指正,谢谢。

来自森大科技官方博客
http://www.cnsendblog.com/index.php/?p=172
GPS平台、网站建设、软件开发、系统运维,找森大网络科技!
http://cnsendnet.taobao.com

原文地址:https://www.cnblogs.com/cnsend/p/12045225.html

时间: 2024-10-31 16:35:16

LINQ入门(下篇)的相关文章

Asp.net之LINQ入门视频教程

当前位置: 主页 > 编程开发 > Asp.net视频教程 > Asp.net之LINQ入门视频教程 > http://www.xin1234.com/Program/AspnetShiPin/AspNetLINQYmSp/ 1.掌握LINQ中的基本概念 上传日期:2014-09-17 02:57:38 相关摘要: - LINQ有关的语言特性:隐式类型 - 网络不稳定的基本处理方法 - python的编程概念比较全面,比vba来得全面,适用范围也广得多了 2.理解扩展方法Lambd

新注册第一帖----------------------乱码新手自学.net 之Linq 入门篇

作为一个业余开发,断断续续学.net/c#也有不少日子了, 学习过程中,不断忘了学,学了忘,这让我很苦恼. 以前学习过程中,我总是在笔记本中记录下来知识要点,这么久下来,笔记本都写了四五本了. 然而,随着笔记本的增多,自己很快发现,笔记写了跟没写一样:笔记多了就找不到了-- 所以,我觉得还是上博客园写博客,记录自己每天的学习心得. 如果有什么错误的地方,欢迎大神指教,小弟在这给大神跪谢了 ======================================================

Linq之旅:Linq入门详解(Linq to Objects)

示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集成查询).通过LINQ,我们可以使用相同API操作不同的数据源.接下来就让我们看看LINQ是什么以及如何使用? 再此之前,需要先了解的相关技术 1. 隐式类型.匿名类型.对象初始化器 1) 隐式类型,使用var关键字创建,C#编译器会根据用于初始化局部变量的初始值推断出变量的数据类型.(不过我个人认

LINQ入门(中篇)

来自森大科技官方博客http://www.cnsendblog.com/index.php/?p=163GPS平台.网站建设.软件开发.系统运维,找森大网络科技!http://cnsendnet.taobao.com 到现在为止你还未触碰LINQ,那进来吧 —— LINQ入门(中篇) 前言 在上篇中简单的分享了LINQ的基础概念及基础语法,如果没有阅读过上篇的朋友可以点击这里.感谢大家的支持,本篇我们将更进一步的学习LINQ的一些相关特性及应用方法.废话不多说,请往下阅读吧. 延迟加载 在上篇中

LINQ入门(完结篇)

来自森大科技官方博客http://www.cnsendblog.com/index.php/?p=175GPS平台.网站建设.软件开发.系统运维,找森大网络科技!http://cnsendnet.taobao.com 到现在为止你还未触碰LINQ,那进来吧 -- LINQ入门(完结篇)前 言 各种懒惰,各种拖沓,终究是要动笔写终结篇了,在这个系列的前几篇文章里我们主要学习linq的基础语法以及他对内存数据的操作等,那么本篇文章我们将讨论学习最为大家所熟悉的,也是最受争议的 Linq To SQL

linq入门系列导航

写在前面 为什么突然想起来学学linq呢?还是源于在跟一个同事聊天的时候,说到他们正在弄得一个项目,在里面用到了linq to sql.突然想到距上次使用linq to sql是三年前的事情了.下班回到家,翻看了电脑上面关于linq的笔记,它已经逃得无影无踪了.也怪我,没事瞎折腾电脑,早不知道放哪儿了,隐隐约约记得之前写过这样的笔记.没办法,只能重新整理学习了.这也是临近春节,还是把导航放出来吧,感兴趣的,有想回家给自己充充电的,也可以参考一下. 系列文章 Linq之Lambda表达式初步认识

Linq入门——什么是linq &amp; 扩展方法

一,什么是Linq linq(language integrated Query):语言集成查询: linq包含如下: 对对象的查询,对数据库的查询,对XML的查询. 那么,没有linq前我们是怎样查询的? 先看一个例子: 现在我们要查询大于50的数,: 在没有linq之前,我们的代码时这样的: 使用了linq查询: 首先,从直观上看,代码更加简洁,其次,对于查询部分,接近SQL语句,层次清晰,容易理解: 除了简单高效以为,LINQ的出现解决了很多问题: 1,面向对象与数据访问两个领域长期分裂,

Javascript快速入门(下篇)

Javascript, cheer up. Ajax:其通过在Web页面与服务器之间建立一个额外的处理层,这个处理层就被称为Ajax引擎,它解释来自用户的请求,在后台以异步的方式处理服务器通信,其结构如下图所示. XMLHttpRequest对象:这个是Ajax的核心对象,其让Javascript构建的HTTP请求并提交给服务器,这样页面就能以异步方式在后台产生请求,让用户可以继续使用这个页面,而不必等待浏览器刷新或加载新的页面.接下来通过一个表格对XMLHttpRequest对象有个总体的了解

LINQ入门

LINQ 是C#中内置的查询语言,感觉和Sql比较类似,主要包括了LINQ to Object,LINQ to XML,LINQ to SQL为不同类型的数据提供了解决方案.暂时只看了LINQ to Object部分,后面的等我看完再补上. 从简单的数组开始,设有一个数组int[] nums存放者大量数据,现在用LINQ来查找其中>1000的存在,并从大到小排序. var sqlResult = from n in nums where n >1000 orderby descending s