<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
LINQ to Objects (C#) | Microsoft 官方檔案
“LINQ to Objects” 指直接將 LINQ 查詢與任何 IEnumerable 或 IEnumerable 集合一起使用。
可以使用 LINQ 來查詢任何可列舉的集合,例如 List、Array 或Dictionary<TKey,TValue>。 該集合可以是使用者定義的集合,也可以是由 .NET Framework API 返回的集合。
“LINQ to Objects”表示一種新的處理集合的方法。 採用舊方法,必須編寫指定如何從集合檢索資料的複雜的 foreach 迴圈。 而採用 LINQ 方法,只需編寫描述要檢索的內容的宣告性程式碼。
此外,LINQ 查詢與傳統 foreach 迴圈相比具有三大優勢:
Linq查詢的延遲計算原理:通過給LINQ擴充套件方法傳遞方法委託,作為yield迭代器的主體,讓遍歷執行到MoveNext()時才執行耗時的指令。
以下程式碼我們原本的期望結果是:刪除掉字串中所有的原音字母。但現在只刪除’u’,因為item變數是迴圈外部宣告的,同一個變數重複宣告更新,所以當最後賦值時,item記錄的是最後一個值為'u'。在foreach才真正執行Where查詢。
IEnumerable<char> query = "Not what you might expect"; var item = 'a'; query = query.Where(c => c != item); item = 'e'; query = query.Where(c => c != item); item = 'i'; query = query.Where(c => c != item); item = 'o'; query = query.Where(c => c != item); item = 'u'; query = query.Where(c => c != item); foreach (char c in query) Console.Write(c); // 只刪除了'u'----Not what yo might expect
按字母順序整理:
Cast,Concat,DefaultIfEmpty,Distinct,Except,GroupBy,GroupJoin,Intersect,Join,OfType,OrderBy,OrderByDescending ,Repeat,Reverse,Select,SelectMany,Skip,SkipWhile,Take,TakeWhile,ThenBy,ThenByDescending,Union,Where,Zip
Aggregate,All,Any,Average,Contains,Count,ElementAt,ElementAtOrDefault,Empty,First,FirstOrDefault,Last,LastOrDefault ,LongCount,Max,Min,Range,SequenceEqual,Single,SingleOrDefault,Sum,ToArray,ToDictionary,ToList,ToLookup
注意:特殊的AsEnumerable運運算元,用於處理LINQ to Entities操作遠端資料來源,將IQueryable遠端資料立即轉化為原生的IEnumerable集合。若AsEnumerable接收引數是IEnumerable記憶體集合則什麼都不做。
LINQ 可用於查詢和轉換字串和字串集合。它對文字檔案中的半結構化資料尤其有用。LINQ 查詢可與傳統的字串函數和正規表示式結合使用。
例如:
請注意,若要執行計數,請先呼叫 Split 方法來建立詞陣列。Split 方法存在效能開銷。如果對字串執行的唯一操作是計數詞,則應考慮改用 Matches 或 IndexOf 方法。
string text = @"Historically, the world of data and the world of objects" + @" have not been well integrated. "; string searchTerm = "data"; //字串轉換成陣列 string[] source = text.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries); // 建立查詢,並忽略大小寫比較 var matchQuery = from word in source where word.ToLowerInvariant() == searchTerm.ToLowerInvariant() select word; // 統計匹配數量. int wordCount = matchQuery.Count(); Console.WriteLine("{0} occurrences(s) of the search term "{1}" were found.", wordCount, searchTerm); //1 occurrences(s) of the search term "data" were found.
在此範例中,查詢將返回包含單詞“Historically,”、“data,”和“integrated”的句子。 雖然在此範例中搜尋條件陣列是寫死的,但也可以在執行時動態填充此陣列。
string text = @"Historically, the world of data and the world of objects " + @"have not been well integrated. Programmers work in C# or Visual Basic " + @"and also in SQL or XQuery. On the one side are concepts such as classes, " + @"objects, fields, inheritance, and .NET Framework APIs. On the other side " + @"are tables, columns, rows, nodes, and separate languages for dealing with " + @"them. Data types often require translation between the two worlds; there are " + @"different standard functions. Because the object world has no notion of query, a " + @"query can only be represented as a string without compile-time type checking or " + @"IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to " + @"objects in memory is often tedious and error-prone."; // 將文字塊切割成陣列. string[] sentences = text.Split(new char[] { '.', '?', '!' }); // 定義搜尋條件,此列表可以執行時動態新增. string[] wordsToMatch = { "Historically", "data", "integrated" }; // 去重,取交集後的數量對比 var sentenceQuery = from sentence in sentences let w = sentence.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries) where w.Distinct().Intersect(wordsToMatch).Count() == wordsToMatch.Count() select sentence; // 執行這個查詢 foreach (string str in sentenceQuery) { Console.WriteLine(str); } //Historically, the world of data and the world of objects have not been well integrated
查詢執行時首先將文字拆分成句子,然後將句子拆分成包含每個單詞的字串陣列。對於每個這樣的陣列,Distinct 方法移除所有重複的單詞,然後查詢對單詞陣列和 wordstoMatch 陣列執行 Intersect 操作。如果交集的計數與 wordsToMatch 陣列的計數相同,則在單詞中找到了所有的單詞,且返回原始句子。
在對 Split 的呼叫中,使用標點符號作為分隔符,以從字串中移除標點符號。如果您沒有這樣做,則假如您有一個字串“Historically,”,該字串不會與 wordsToMatch 陣列中的“Historically”相匹配。根據源文字中標點的型別,您可能必須使用其他分隔符。
因為 String 類實現泛型 IEnumerable 介面,所以可以將任何字串作為字元序列進行查詢。但是,這不是 LINQ 的常見用法。若要執行復雜的模式匹配操作,請使用 Regex 類。
以下範例查詢一個字串以確定它所包含的數位數量。 請注意,在第一次執行此查詢後將“重用”此查詢。 這是可能的,因為查詢本身並不儲存任何實際的結果。
string aString = "ABCDE99F-J74-12-89A"; // 只選擇數位的字元 IEnumerable<char> stringQuery = from ch in aString where Char.IsDigit(ch) select ch; // 執行這個查詢 foreach (char c in stringQuery) Console.Write(c + " "); //9 9 7 4 1 2 8 9 // 對上面的查詢呼叫Count方法 int count = stringQuery.Count(); Console.WriteLine("Count = {0}", count); //Count = 8 // 選擇第一個「-」之前的所有字元 IEnumerable<char> stringQuery2 = aString.TakeWhile(c => c != '-'); // 執行第二個查詢 foreach (char c in stringQuery2) Console.Write(c); //ABCDE99F
此範例演示如何使用 Regex 類建立正規表示式以便在文字字串中進行更復雜的匹配。使用 LINQ 查詢可以方便地對您要用正規表示式搜尋的檔案進行準確篩選,以及對結果進行加工。
//根據不同版本的 vs 修改路徑 string startFolder = @"C:Program Files (x86)Microsoft Visual Studio 11.0"; IEnumerable fileList = Directory.GetFiles(startFolder, "*.*", SearchOption.AllDirectories).Select(p => new System.IO.FileInfo(p)); //建立正規表示式來尋找所有的"Visual" Regex searchTerm = new Regex(@"Visual (Basic|C#|C++|Studio)"); //搜尋每一個「.htm」檔案 //通過 where 找到匹配項 //注意:select 中的變數要求顯示宣告其型別,因為 MatchCollection 不是泛型 IEnumerable 集合 var queryMatchingFiles = from file in fileList where file.Extension == ".htm" let fileText = File.ReadAllText(file.FullName) let matches = searchTerm.Matches(fileText) where matches.Count > 0 select new { name = file.FullName, matchedValues = from Match match in matches select match.Value }; foreach (var v in queryMatchingFiles) { //修剪匹配找到的檔案中的路徑 string s = v.name.Substring(startFolder.Length - 1); Console.WriteLine(s); //輸出找到的匹配值 foreach (var v2 in v.matchedValues) { Console.WriteLine(" " + v2); } } //professional2052License.htm // Visual Studio // Visual Studio // Visual Studio //VBVBWizardsFrameSetTemplates1033BanToc.htm // Visual Studio
還可以查詢由 RegEx 搜尋返回的 MatchCollection 物件。在此範例中,結果中僅生成每個匹配項的值。但也可使用 LINQ 對該集合執行各種篩選、排序和分組操作。
【注意】由於 MatchCollection 是非泛型 IEnumerable 集合,因此必須顯式宣告查詢中的範圍變數的型別。
許多不同型別的文字檔案都包含一系列行,通常具有類似的格式設定,例如製表符分隔或逗號分隔的檔案或固定長度的行。
將此類文字檔案讀入記憶體後,可以使用 LINQ 來查詢和/或修改其中的行。 LINQ 查詢還簡化了合併來自多個源的資料的任務。
此範例演示如何使用 LINQ 對兩個字串列表進行比較,並輸出那些位於 names1.txt 中但不在 names2.txt 中的行。
names1.txt
Bankov, Peter
Holm, Michael
Garcia, Hugo
Potra, Cristina
Noriega, Fabricio
Aw, Kam Foo
Beebe, Ann
Toyoshima, Tim
Guy, Wey Yuan
Garcia, Debra
names2.txt
Liu, Jinghao
Bankov, Peter
Holm, Michael
Garcia, Hugo
Beebe, Ann
Gilchrist, Beth
Myrcha, Jacek
Giakoumakis, Leo
McLin, Nkenge
El Yassir, Mehdi
程式碼:
//建立資料來源 var names1Text = File.ReadAllLines(@"names1.txt"); var names2Text = File.ReadAllLines(@"names2.txt"); //建立查詢,這裡必須使用方法語法 var query = names1Text.Except(names2Text); //執行查詢 Console.WriteLine("The following lines are in names1.txt but not names2.txt"); foreach (var name in query) { Console.WriteLine(name); }
【注意】某些型別的查詢操作(如 Except、Distinct、Union 和 Concat)只能用基於方法的語法表示。
下面的範例演示如何按結構化文字(如逗號分隔值)行中的任意欄位對該文字行進行排序。可在執行時動態指定該欄位。此範例還演示如何從方法返回查詢變數。
scores.csv:假定 scores.csv 中的欄位表示學生的 ID 號,後面跟四個測驗分數。
111, 97, 92, 81, 60
112, 75, 84, 91, 39
113, 88, 94, 65, 91
114, 97, 89, 85, 82
115, 35, 72, 91, 70
116, 99, 86, 90, 94
117, 93, 92, 80, 87
118, 92, 90, 83, 78
119, 68, 79, 88, 92
120, 99, 82, 81, 79
121, 96, 85, 91, 60
122, 94, 92, 91, 91
// 建立資料來源 string[] scores = System.IO.File.ReadAllLines(@"scores.csv"); // 可以改為 0~4 的任意值 int sortField = 1; Console.WriteLine("Sorted highest to lowest by field [{0}]:", sortField); //演示從方法返回查詢,這裡執行查詢 foreach (string str in RunQuery(scores, sortField)) { Console.WriteLine(str); } // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit"); // 返回查詢變數,非查詢結果 static IEnumerable<string> RunQuery(IEnumerable<string> source, int num) { // 分割字串來排序 var scoreQuery = from line in source let fields = line.Split(',') orderby fields[num] descending select line; return scoreQuery; } /* Output (if sortField == 1): Sorted highest to lowest by field [1]: 116, 99, 86, 90, 94 120, 99, 82, 81, 79 111, 97, 92, 81, 60 114, 97, 89, 85, 82 121, 96, 85, 91, 60 122, 94, 92, 91, 91 117, 93, 92, 80, 87 118, 92, 90, 83, 78 113, 88, 94, 65, 91 112, 75, 84, 91, 39 119, 68, 79, 88, 92 115, 35, 72, 91, 70 */
逗號分隔值 (CSV) 檔案是一種文字檔案,通常用於儲存電子試算表資料或其他由行和列表示的表格資料。通過使用 Split 方法分隔欄位,可以非常輕鬆地使用 LINQ 來查詢和操作 CSV 檔案。事實上,可以使用此技術來重新排列任何結構化文字行部分;此技術不侷限於 CSV 檔案。
在下面的範例中,假定有三列分別代表學生的“姓氏”、“名字”和“ID”。這些欄位基於學生的姓氏按字母順序排列。查詢生成一個新序列,其中首先出現的是 ID 列,後面的第二列組合了學生的名字和姓氏。根據 ID 欄位重新排列各行。結果儲存到新檔案,但不修改原始資料。
spreadsheet1.csv
Adams,Terry,120
Fakhouri,Fadi,116
Feng,Hanying,117
Garcia,Cesar,114
Garcia,Debra,115
Garcia,Hugo,118
Mortensen,Sven,113
O'Donnell,Claire,112
Omelchenko,Svetlana,111
Tucker,Lance,119
Tucker,Michael,122
Zabokritski,Eugene,121
程式碼
//資料來源 var lines = File.ReadAllLines(@"spreadsheet1.csv"); //將舊資料的第2列的欄位放到第一位,逆向結合第0列和第1列的欄位 var query = from line in lines let t = line.Split(',') orderby t[2] select $"{t[2]}, {t[1]} {t[0]}"; foreach (var q in query) { Console.WriteLine(q); } //寫入檔案 File.WriteAllLines("spreadsheet2.csv", query);
此範例演示如何合併包含文字行的檔案,然後排序結果。具體來說,此範例演示如何對兩組文字行執行簡單的串聯、聯合和交集。
names1.txt
Bankov, Peter
Holm, Michael
Garcia, Hugo
Potra, Cristina
Noriega, Fabricio
Aw, Kam Foo
Beebe, Ann
Toyoshima, Tim
Guy, Wey Yuan
Garcia, Debra
names2.txt
Liu, Jinghao
Bankov, Peter
Holm, Michael
Garcia, Hugo
Beebe, Ann
Gilchrist, Beth
Myrcha, Jacek
Giakoumakis, Leo
McLin, Nkenge
El Yassir, Mehdi
程式碼:
var names1Text = File.ReadAllLines(@"names1.txt"); var names2Text = File.ReadAllLines(@"names2.txt"); //簡單連線,並排序。重複儲存。 var concatQuery = names1Text.Concat(names2Text).OrderBy(x => x); OutputQueryResult(concatQuery, "Simple concatenate and sort. Duplicates are preserved:"); //基於預設字串比較器連線,並刪除重複。 var unionQuery = names1Text.Union(names2Text).OrderBy(x => x); OutputQueryResult(unionQuery, "Union removes duplicate names:"); //查詢在兩個檔案中出現的名稱 var intersectQuery = names1Text.Intersect(names2Text).OrderBy(x => x); OutputQueryResult(intersectQuery, "Merge based on intersect:"); //在每個列表中找到匹配的欄位。使用 concat 將兩個結果合併,然後使用預設的字串比較器進行排序 const string nameMatch = "Garcia"; var matchQuery1 = from name in names1Text let t = name.Split(',') where t[0] == nameMatch select name; var matchQuery2 = from name in names2Text let t = name.Split(',') where t[0] == nameMatch select name; var temp = matchQuery1.Concat(matchQuery2).OrderBy(x => x); OutputQueryResult(temp, $"Concat based on partial name match "{nameMatch}":"); private static void OutputQueryResult(IEnumerable<string> querys, string title) { Console.WriteLine(Environment.NewLine + title); foreach (var query in querys) { Console.WriteLine(query); } Console.WriteLine($"{querys.Count()} total names in list"); }
不要嘗試將記憶體中的資料或檔案系統中的資料與仍在資料庫中的資料相聯接。此種跨域聯接會生成未定義的結果,因為資料庫查詢和其他型別的源定義聯接運算的方式可能不同。另外,如果資料庫中的資料量足夠大,則存在此類運算引發記憶體不足異常的風險。
若要將資料庫資料與記憶體中的資料相聯接,請首先對資料庫查詢呼叫 ToList 或 ToArray,然後對返回的集合執行聯接。
//每行 names.csv 包含姓氏,名字,和身份證號,以逗號分隔。例如,Omelchenko,Svetlana,111 var names = File.ReadAllLines(@"names.csv"); //每行 scores.csv 包括身份證號碼和四個測試評分,以逗號分隔。例如,111,97,92,81,60 var scores = File.ReadAllLines(@"scores.csv"); //使用一個匿名的型別合併資料來源。 //【注意】動態建立一個 int 的考試成績成員列表。 //跳過分割字串中的第一項,因為它是學生的身份證,不是一個考試成績 var students = from name in names let t = name.Split(',') from score in scores let t2 = score.Split(',') where t[2] == t2[0] select new { FirstName = t[0], LastName = t[1], ID = Convert.ToInt32(t[2]), ExamScores = (from scoreAsText in t2.Skip(1) select Convert.ToInt32(scoreAsText)).ToList() }; //顯示每個學生的名字和考試平均成績。 foreach (var student in students) { Console.WriteLine( $"The average score of {student.FirstName} {student.LastName} is {student.ExamScores.Average()}."); }
此範例演示如何聯接兩個逗號分隔檔案中的資料,這兩個檔案共用一個用作匹配鍵的共同值。如果您必須將兩個電子試算表的資料或一個電子試算表和一個其他格式的檔案的資料組合為一個新檔案,則此技術很有用。還可以修改此範例以適合任意種類的結構化文字。
names.csv:此檔案表示一個電子試算表。該電子試算表包含學生的姓氏、名字和學生 ID。
Omelchenko,Svetlana,111
O'Donnell,Claire,112
Mortensen,Sven,113
Garcia,Cesar,114
Garcia,Debra,115
Fakhouri,Fadi,116
Feng,Hanying,117
Garcia,Hugo,118
Tucker,Lance,119
Adams,Terry,120
Zabokritski,Eugene,121
Tucker,Michael,122
scores.csv:此檔案表示電子試算表資料。第 1 列是學生的 ID,第 2 至 5 列是測驗分數。
111, 97, 92, 81, 60
112, 75, 84, 91, 39
113, 88, 94, 65, 91
114, 97, 89, 85, 82
115, 35, 72, 91, 70
116, 99, 86, 90, 94
117, 93, 92, 80, 87
118, 92, 90, 83, 78
119, 68, 79, 88, 92
120, 99, 82, 81, 79
121, 96, 85, 91, 60
122, 94, 92, 91, 91
程式碼:
var names = File.ReadAllLines(@"names.csv"); var scores = File.ReadAllLines(@"scores.csv"); //Name: Last[0], First[1], ID[2] // Omelchenko, Svetlana, 11 //Score: StudentID[0], Exam1[1] Exam2[2], Exam3[3], Exam4[4] // 111, 97, 92, 81, 60 //該查詢基於 id 連線兩個不同的電子試算表 var query = from name in names let t1 = name.Split(',') from score in scores let t2 = score.Split(',') where t1[2] == t2[0] orderby t1[0] select $"{t1[0]},{t2[1]},{t2[2]},{t2[3]},{t2[4]}"; //輸出 OutputQueryResult(query, "Merge two spreadsheets:"); private static void OutputQueryResult(IEnumerable<string> querys, string title) { Console.WriteLine(Environment.NewLine + title); foreach (var query in querys) { Console.WriteLine(query); } Console.WriteLine($"{querys.Count()} total names in list"); }
此範例演示一種進行以下操作的方法:合併兩個檔案的內容,然後建立一組以新方式組織資料的新檔案。
name1.txt
Bankov, Peter
Holm, Michael
Garcia, Hugo
Potra, Cristina
Noriega, Fabricio
Aw, Kam Foo
Beebe, Ann
Toyoshima, Tim
Guy, Wey Yuan
Garcia, Debra
name2.text
Liu, Jinghao
Bankov, Peter
Holm, Michael
Garcia, Hugo
Beebe, Ann
Gilchrist, Beth
Myrcha, Jacek
Giakoumakis, Leo
McLin, Nkenge
El Yassir, Mehdi
name2.txt
Liu, Jinghao
Bankov, Peter
Holm, Michael
Garcia, Hugo
Beebe, Ann
Gilchrist, Beth
Myrcha, Jacek
Giakoumakis, Leo
McLin, Nkenge
El Yassir, Mehdi
程式碼:
var fileA = File.ReadAllLines(@"names1.txt"); var fileB = File.ReadAllLines(@"names2.txt"); //並集:連線並刪除重複的名字 var mergeQuery = fileA.Union(fileB); //根據姓氏的首字母對姓名進行分組 var query = from name in mergeQuery let t = name.Split(',') group name by t[0][0] into g orderby g.Key select g; //為建立的每個組建立一個新檔案,請注意,需要使用巢狀的foreach迴圈來存取每個組的單個項。 foreach (var g in query) { var fileName = @"testFile_" + g.Key + ".txt"; Console.WriteLine(g.Key + ":"); //寫入檔案 using (var sw = new StreamWriter(fileName)) { foreach (var name in g) { sw.WriteLine(name); Console.WriteLine(" " + name); } } }
對於與資料檔案位於同一資料夾中的每個組,程式將為這些組編寫單獨的檔案。
此範例演示如何對 .csv 檔案的列執行諸如 Sum、Average、Min 和 Max 等聚合計算。此處所示的範例原則可以應用於其他型別的結構化文字。
scores.csv
111, 97, 92, 81, 60
112, 75, 84, 91, 39
113, 88, 94, 65, 91
114, 97, 89, 85, 82
115, 35, 72, 91, 70
116, 99, 86, 90, 94
117, 93, 92, 80, 87
118, 92, 90, 83, 78
119, 68, 79, 88, 92
120, 99, 82, 81, 79
121, 96, 85, 91, 60
122, 94, 92, 91, 91
scores.csv:假定第一列表示學員 ID,後面幾列表示四次考試的分數。
var scores = File.ReadAllLines(@"scores.csv"); //指定要計算的列 const int examNum = 3; //scores.csv 格式: //Student ID Exam#1 Exam#2 Exam#3 Exam#4 //111, 97, 92, 81, 60 //+1 表示跳過第一列 //計算單一列 SingleColumn(scores, examNum + 1); Console.WriteLine(); //計算多列 MultiColumns(scores); private static void SingleColumn(IEnumerable<string> strs, int examNum) { Console.WriteLine("Single Column Query:"); //查詢分兩步: // 1.分割字串 // 2.對要計算的列的值轉換為 int var query = from str in strs let t = str.Split(',') select Convert.ToInt32(t[examNum]); //對指定的列進行統計 var average = query.Average(); var max = query.Max(); var min = query.Min(); Console.WriteLine($"Exam #{examNum}: Average:{average:##.##} High Score:{max} Low Score:{min}"); } private static void MultiColumns(IEnumerable<string> strs) { Console.WriteLine("Multi Column Query:"); //查詢步驟: // 1.分割字串 // 2.跳過 id 列(第一列) // 3.將當前行的每個評分都轉換成 int,並選擇整個序列作為一行結果。 var query = from str in strs let t1 = str.Split(',') let t2 = t1.Skip(1) select (from t in t2 select Convert.ToInt32(t)); //執行查詢並快取結果以提高效能 var results = query.ToList(); //找出結果的列數 var count = results[0].Count(); //執行統計 //為每一列分數的迴圈執行一次迴圈 for (var i = 0; i < count; i++) { var query2 = from result in results select result.ElementAt(i); var average = query2.Average(); var max = query2.Max(); var min = query2.Min(); //+1 因為 #1 表示第一次考試 Console.WriteLine($"Exam #{i + 1} Average: {average:##.##} High Score: {max} Low Score: {min}"); } }
查詢的工作原理是使用 Split 方法將每一行文字轉換為陣列。每個陣列元素表示一列。最後,每一列中的文字都轉換為其數位表示形式。如果檔案是製表符分隔檔案,只需將 Split 方法中的引數更新為 t。
下面的程式碼對字串陣列執行 LINQ 查詢。
該查詢使用 let
子句將每個字串分隔成欄位陣列。
// Create the text file. string csvString = @"GREAL,Great Lakes Food Market,Howard Snyder,Marketing Manager,(503) 555-7555,2732 Baker Blvd.,Eugene,OR,97403,USA HUNGC,Hungry Coyote Import Store,Yoshi Latimer,Sales Representative,(503) 555-6874,City Center Plaza 516 Main St.,Elgin,OR,97827,USA LAZYK,Lazy K Kountry Store,John Steel,Marketing Manager,(509) 555-7969,12 Orchestra Terrace,Walla Walla,WA,99362,USA LETSS,Let's Stop N Shop,Jaime Yorres,Owner,(415) 555-5938,87 Polk St. Suite 5,San Francisco,CA,94117,USA"; File.WriteAllText("cust.csv", csvString); // Read into an array of strings. string[] source = File.ReadAllLines("cust.csv"); XElement cust = new XElement("Root", from str in source let fields = str.Split(',') select new XElement("Customer", new XAttribute("CustomerID", fields[0]), new XElement("CompanyName", fields[1]), new XElement("ContactName", fields[2]), new XElement("ContactTitle", fields[3]), new XElement("Phone", fields[4]), new XElement("FullAddress", new XElement("Address", fields[5]), new XElement("City", fields[6]), new XElement("Region", fields[7]), new XElement("PostalCode", fields[8]), new XElement("Country", fields[9]) ) ) ); Console.WriteLine(cust);
到此這篇關於C#中LINQ to Objects的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45