国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C# > 正文

詳解LINQ入門(mén)(下篇)

2020-01-24 00:01:06
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前 言

終于來(lái)到下篇了,通過(guò)上篇,和中篇,我們了解了linq的基本語(yǔ)句,對(duì)應(yīng)linq我們又了解到lambda表達(dá)式,靜態(tài)擴(kuò)展方法,以及l(fā)inq的延遲加載的特性,那么在本篇文章中我們將分享學(xué)習(xí)一下linq對(duì)于我們開(kāi)發(fā)中常用到的對(duì)象的操作應(yīng)用。如果沒(méi)有閱讀過(guò)上篇的請(qǐng)點(diǎn)擊這里,如果沒(méi)有閱讀中篇的請(qǐng)點(diǎn)擊這里

linq to DataSet

對(duì)于做.net 開(kāi)發(fā)的有誰(shuí)不知道DataSet,DataTable,DataRow,DataColumn這些對(duì)象,如果你真的不知道,那好吧建議你到菜市場(chǎng)買(mǎi)2塊豆腐撞死算了>_<。也許你會(huì)驚訝,哇靠!linq能操作這些?答案是肯定的。那么我們來(lái)看看linq是怎么操作的。

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

using System.Data;using System.Linq;

2. 關(guān)鍵方法 AsEnumerable,該方法為一個(gè)靜態(tài)擴(kuò)展方法,他將DataTable轉(zhuǎn)換為一個(gè)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);// 重點(diǎn)看這里IEnumerable<DataRow> rows = dt.AsEnumerbale();foreach(row in rows)  Console.WriteLine(row["A"].ToString());

從這段代碼看,并沒(méi)有什么實(shí)質(zhì)意義,如果這樣去遍歷datarow就是脫褲子放屁,多此一舉。但是這樣做的目只有一個(gè)為下面的linq操作做鋪墊。

3. linq 對(duì) DataRow 操作,以下舉例一些linq特有的常用datarow操作

Distinct,顧名思義該方法返回的沒(méi)有重復(fù)值的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);// 重點(diǎn)看這里IEnumerable<DataRow> rows = dt.AsEnumerbale();// 去重復(fù)IEnumerable<DataRow> distinctRows = rows.Distinct(DataRowComparer.Default);foreach(var row in distictRows)  Console.WriteLine(row["A"].ToString());// 結(jié)果// 1// 2

注意,這里的 DataRowComparer 是一個(gè)靜態(tài)類,屬性 Default 表示返回單一的DataRow實(shí)例

Except, 找到DataRow序列A中在datarow序列B中沒(méi)有的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 });// 重點(diǎn)看這里IEnumerable<DataRow> rows1 = dt1.AsEnumerable();IEnumerable<DataRow> rows2 = dt2.AsEnumerable();// 獲取rows1中在rows2里沒(méi)有包含的datarow序列var rows3 = rows1.Except(rows2, DataRowComparer.Default);foreach (var row in rows3)  Console.WriteLine(row["A"].ToString());// 結(jié)果// 1

Intersect, 兩個(gè)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});// 重點(diǎn)看這里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());// 結(jié)果// 2

Union,合并兩個(gè)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 });// 重點(diǎn)看這里IEnumerable<DataRow> rows1 = dt1.AsEnumerable();IEnumerable<DataRow> rows2 = dt2.AsEnumerable();// 合并rows1與rows2var row3 = rows1.Union(rows2, DataRowComparer.Default);foreach (var row in row3)  Console.WriteLine(row["A"].ToString());// 結(jié)果// 1// 2// 3

SequenceEqual,判斷兩個(gè)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});// 重點(diǎn)看這里IEnumerable<DataRow> rows1 = dt1.AsEnumerbale();IEnumerable<DataRow> rows2 = dt2.AsEnumerbale();// 合并rows1與rows2var equal = rows1.SequenceEqual(row2, DataRowComparer.Default); Console.WriteLine(equal.ToString());// 結(jié)果// false

4. linq 對(duì) DataColumn 操作

在了解了對(duì)datarow的操作后,我們?cè)賮?lái)了解一下對(duì)datacolumn的操作

Field<T> , 它是一個(gè)獲取當(dāng)前行(datarow)的某一列值的靜態(tài)擴(kuò)展方法,它具有三種重載參數(shù),類型分別是DataColumn, String, Int,在這里建議大家使用string 類型參數(shù),明確是取哪一列,語(yǔ)句閱讀上更流暢。

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();// 重點(diǎn)看這里foreach(var val in rows.Select(e => e.Field<int>("A"))  Console.WriteLine(val.ToString());

SetField<T> , 該方法剛好是對(duì)當(dāng)前行某一列進(jìn)行賦值操作,同樣也具有三種重載參數(shù)DataColumn, String, Int,在這里建議大家使用string 類型參數(shù),明確是取哪一列,語(yǔ)句閱讀上更流暢。

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();// 重點(diǎn)看這里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())// 結(jié)果// 11// 12

5. CopyToDataTable<DataRow>,該方法是將datarow序列組成一個(gè)新的DataTable

// 已知一個(gè)DataTablevar dt = new DataTable();// 獲取一個(gè)DataRow序列var rows = dt.AsEnumerable();//經(jīng)過(guò)一系列操作// ....//獲取一個(gè)新的DataTablevar newDt = rows.CopyToDataTable();

至此,我們對(duì)linq to DataSet 有了一個(gè)基本認(rèn)識(shí)與了解,那么下面我們將了解另一個(gè)應(yīng)用 linq to xml

 linq to XML

在實(shí)際應(yīng)用中,并不需要我們使用linq對(duì)xml對(duì)象進(jìn)行操作,因?yàn)镸S已經(jīng)提供了封裝對(duì)xml的linq操作的對(duì)象,我們一起來(lái)簡(jiǎn)單的了解下有哪些對(duì)象。

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

using System.Linq;using System.Xml.Linq;

2. linq to xml 主要類型對(duì)象

  • XDocument : 表示 XML 文檔
  • XElement : 表示一個(gè) XML 元素
  • XAttribute : 表示一個(gè) XML 特性(節(jié)點(diǎn)屬性)
  • XNamespace : 表示一個(gè) XML 命名空間
  • XCData : 表示一個(gè)包含 CDATA 的文本節(jié)點(diǎn)(注釋)
  • XDeclaration : 表示一個(gè) XML 聲明
 // 創(chuàng)建一個(gè)XML文檔var xDoc = new XDocument(  // 定義聲明  new XDeclaration("1.0", "utf-8", "yes"),    // 添加根節(jié)點(diǎn)    new XElement("root",      // 添加子節(jié)點(diǎn)1,并添加節(jié)點(diǎn)屬性“name”      new XElement("item1", new XAttribute("name","屬性"), "子節(jié)點(diǎn)1"),      // 添加子節(jié)點(diǎn)2,并添加內(nèi)容注釋CDATA      new XElement("item2", new XCData("注釋"))));// 輸出結(jié)果//<?xml version="1.0" encoding="utf-8" standalone="yes"?>//<root>// <item1 name="屬性">子節(jié)點(diǎn)1</item1>// <item2><![CDATA[注釋]]></item2>//</root>

2. 輸出XML文檔,當(dāng)我們創(chuàng)建好一個(gè)xml文檔對(duì)象時(shí),調(diào)用該對(duì)象的方法 Save 即可,如下:

// 創(chuàng)建一個(gè)XML文檔var xDoc = new XDocument(  // 定義聲明  new XDeclaration("1.0", "utf-8", "yes"),    // 添加根節(jié)點(diǎn)    new XElement("root",      // 添加子節(jié)點(diǎn)1,并添加節(jié)點(diǎn)屬性“name”      new XElement("item1", new XAttribute("name","屬性"), "子節(jié)點(diǎn)1"),      // 添加子節(jié)點(diǎn)2,并添加內(nèi)容注釋CDATA      new XElement("item2", new XCData("注釋"))));// 輸出XML文檔xDoc.Save("demo.xml");

3. 導(dǎo)入xml文檔,如果已知一個(gè)XML文本文件,我們需要獲取這個(gè)xml文本文件XDocment對(duì)象時(shí),可以執(zhí)行改對(duì)象方法 Load,該方法具有八種參數(shù)重載,參數(shù)類型分別是Stream,String,TextReader,XmlReader。下面的示例中使用的是 string 類型參數(shù)傳遞

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

4. XNode 抽象基類,表示 XML 樹(shù)中節(jié)點(diǎn)的抽象概念(元素、注釋、文檔類型、處理指令或文本節(jié)點(diǎn)),簡(jiǎn)單理解就是我們可以把XML的內(nèi)容每一個(gè)部分都視為節(jié)點(diǎn),也就是說(shuō)它是類型的基類,并提供了大量的操作xml方法。

摘自MSDN:

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

  • XComment
  • XContainer
  • XDocumentType
  • XProcessingInstruction
  • XText

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

  • XDocument
  • XElement

派生自 XContainer 的類的對(duì)象可以包含子節(jié)點(diǎn)。

5. 常用遍歷方法

  • DescendantNodes : 按文檔順序返回此文檔或元素的子代節(jié)點(diǎn)集合。
  • Elements : 按文檔順序返回此元素或文檔的子元素集合
var xDoc = XDocument.Load("demo.xml");IEnumerable<XNode> nodex = xDoc.DescendantNodes();IEnumerable<XElement> elems = xDoc.Elements();

當(dāng)我們獲取到到節(jié)點(diǎn)或者元素的序列后就可以對(duì)這些對(duì)象進(jìn)行常規(guī)的LINQ操作,例如運(yùn)用前兩篇介紹的知識(shí)。

由于篇幅關(guān)系,這里就不逐一去講解每個(gè)LINQ TO XML的API了,感興趣的讀者可以去msdn查閱System.Xml.Linq命名空間下的操作對(duì)象。

總 結(jié)

(吐槽)當(dāng)我寫(xiě)完這篇文章時(shí),自我感覺(jué)很枯燥,通篇介紹的都是API封裝沒(méi)有體現(xiàn)出LINQ的新意,想刪掉這篇文章的沖動(dòng)都有,但是一想既然我們要學(xué)習(xí)LINQ,這些東西還是需要適當(dāng)了解與接觸,所以還是硬著頭皮寫(xiě)下來(lái)了,如果你能看完整篇文章,那真的非常感謝,感謝你的支持。

linq to xml 在效率上和 xml 的 xpath 差不了多少,所以在什么情況下怎么使用任君選擇,并不需要強(qiáng)制使用的。

linq to dataset 小數(shù)據(jù)的時(shí)候可以這么干,但是數(shù)據(jù)量大時(shí)候,我建議不要這么干,首先要執(zhí)行AsEnumberable這樣一個(gè)耗時(shí)的方法劃不來(lái),不如直接上foreach遍歷。

最終篇將和大家分享并討論最受大家所熟知的LINQ TO SQL,還是希望大家給予一點(diǎn)期待吧。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 阳朔县| 茌平县| 连城县| 七台河市| 凉城县| 临朐县| 潍坊市| 兴化市| 铜陵市| 什邡市| 兰坪| 广德县| 吕梁市| 偃师市| 延寿县| 灵山县| 三原县| 辽阳市| 阿鲁科尔沁旗| 新平| 龙里县| 白朗县| 息烽县| 大竹县| 澄迈县| 邹城市| 体育| 合山市| 呼图壁县| 师宗县| 皮山县| 齐齐哈尔市| 崇仁县| 育儿| 伊吾县| 五河县| 通渭县| 大新县| 锡林浩特市| 新邵县| 青浦区|