C#3.0新增功能09 LINQ 基礎05 使用 LINQ 進行數據轉換

語言集成查詢 (LINQ) 不僅是檢索數據。 它也是用於轉換數據的強大工具。 經過使用 LINQ查詢,可使用源序列做爲輸入,並經過多種方式對其進行修改,以建立新的輸出序列。經過排序和分組,你能夠修改序列自己,而無需修改這些元素自己。 但也許 LINQ 查詢最強大的功能是建立新類型。 這能夠在 select 子句中完成。 例如,能夠執行下列任務:html

  • 將多個輸入序列合併爲具備新類型的單個輸出序列。sql

  • 建立其元素由源序列中每一個元素的一個或多個屬性組成的輸出序列。數據庫

  • 建立其元素由對源數據執行的操做結果組成的輸出序列。express

  • 建立其餘格式的輸出序列。 例如,能夠將數據從 SQL 行或文本文件轉換爲 XML。數據結構

這只是幾個例子。 固然,能夠以各類方式在同一查詢中組合這些轉換。 此外,一個查詢的輸出序列能夠用做新查詢的輸入序列。ide

將多個輸入聯接到一個輸出序列中
可使用 LINQ 查詢建立包含元素的輸出序列,這些元素來自多個輸入序列。 如下示例演示如何組合兩個內存中數據結構,但相同的原則可應用於組合來自 XML 或 SQL 或數據集源的數據。 假設如下兩種類類型:
class Student
{
    public string First { get; set; }
    public string Last {get; set;}
    public int ID { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public List<int> Scores;
}

class Teacher
{
    public string First { get; set; }
    public string Last { get; set; }
    public int ID { get; set; } 
    public string City { get; set; }
}

如下示例演示了查詢:工具

 1 class DataTransformations
 2 {
 3     static void Main()
 4     {
 5         // 建立第一個數據源
 6         List<Student> students = new List<Student>()
 7         {
 8             new Student { First="Svetlana",
 9                 Last="Omelchenko",
10                 ID=111,
11                 Street="123 Main Street",
12                 City="Seattle",
13                 Scores= new List<int> { 97, 92, 81, 60 } },
14             new Student { First="Claire",
15                 Last="O’Donnell",
16                 ID=112,
17                 Street="124 Main Street",
18                 City="Redmond",
19                 Scores= new List<int> { 75, 84, 91, 39 } },
20             new Student { First="Sven",
21                 Last="Mortensen",
22                 ID=113,
23                 Street="125 Main Street",
24                 City="Lake City",
25                 Scores= new List<int> { 88, 94, 65, 91 } },
26         };
27 
28         // 建立第二個數據源
29         List<Teacher> teachers = new List<Teacher>()
30         {                
31             new Teacher { First="Ann", Last="Beebe", ID=945, City="Seattle" },
32             new Teacher { First="Alex", Last="Robinson", ID=956, City="Redmond" },
33             new Teacher { First="Michiyo", Last="Sato", ID=972, City="Tacoma" }
34         };
35         
36         // 建立查詢
37         var peopleInSeattle = (from student in students
38                     where student.City == "Seattle"
39                     select student.Last)
40                     .Concat(from teacher in teachers
41                             where teacher.City == "Seattle"
42                             select teacher.Last);
43 
44         Console.WriteLine("The following students and teachers live in Seattle:");
45         // 執行查詢
46         foreach (var person in peopleInSeattle)
47         {
48             Console.WriteLine(person);
49         }
50         
51         Console.WriteLine("Press any key to exit.");
52         Console.ReadKey();
53     }
54 }
55 /* 輸出:
56     The following students and teachers live in Seattle:
57     Omelchenko
58     Beebe
59  */

有關詳細信息,請參閱 join 子句和 select 子句ui

選擇每一個源元素的子集

有兩種主要方法來選擇源序列中每一個元素的子集:spa

  1. 若要僅選擇源元素的一個成員,請使用點操做。 在如下示例中,假設 Customer 對象包含多個公共屬性,包括名爲 City 的字符串。 在執行時,此查詢將生成字符串的輸出序列。debug

    var query = from cust in Customers  
                select cust.City;
  2. 若要建立包含多個源元素屬性的元素,可使用帶有命名對象或匿名類型的對象初始值設定項。 如下示例演示如何使用匿名類型封裝每一個 Customer 元素的兩個屬性:

    var query = from cust in Customer  
                select new {Name = cust.Name, City = cust.City};

有關詳細信息,請參閱對象和集合初始值設定項匿名類型

將內存中對象轉換爲 XML
LINQ 查詢能夠輕鬆地在內存中數據結構、SQL 數據庫、ADO.NET 數據集和 XML 流或文檔之間轉換數據。 如下示例將內存中數據結構中的對象轉換爲 XML 元素。
 1 class XMLTransform
 2 {
 3     static void Main()
 4     {            
 5         // 使用集合初始值設定項建立數據源
 6         // 學生類是在上述定義的
 7         List<Student> students = new List<Student>()
 8         {
 9             new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores = new List<int>{97, 92, 81, 60}},
10             new Student {First="Claire", Last="O’Donnell", ID=112, Scores = new List<int>{75, 84, 91, 39}},
11             new Student {First="Sven", Last="Mortensen", ID=113, Scores = new List<int>{88, 94, 65, 91}},
12         };
13 
14         // 建立查詢
15         var studentsToXML = new XElement("Root",
16             from student in students
17             let scores = string.Join(",", student.Scores)
18             select new XElement("student",
19                        new XElement("First", student.First),
20                        new XElement("Last", student.Last),
21                        new XElement("Scores", scores)
22                     ) // end "student"
23                 ); // end "Root"
24 
25         // 執行查詢
26         Console.WriteLine(studentsToXML);
27 
28         // Keep the console open in debug mode.
29         Console.WriteLine("Press any key to exit.");
30         Console.ReadKey();
31     }
32 }

此代碼生成如下 XML 輸出:

<Root>  
  <student>  
    <First>Svetlana</First>  
    <Last>Omelchenko</Last>  
    <Scores>97,92,81,60</Scores>  
  </student>  
  <student>  
    <First>Claire</First>  
    <Last>O'Donnell</Last>  
    <Scores>75,84,91,39</Scores>  
  </student>  
  <student>  
    <First>Sven</First>  
    <Last>Mortensen</Last>  
    <Scores>88,94,65,91</Scores>  
  </student>  
</Root>

有關詳細信息,請參閱在 C# 中建立 XML 樹 (LINQ to XML)

對源元素執行操做

輸出序列可能不包含源序列中的任何元素或元素屬性。 輸出多是使用源元素做爲輸入參數而計算得出的值序列。 如下簡單查詢在執行時會輸出一串字符串,其值表示基於 double類型的元素的源序列的計算結果。

若是查詢將被轉換爲另外一個域,則不支持在查詢表達式中調用方法。 例如,不能在 LINQ to SQL 中調用普通的 C# 方法,由於 SQL Server 沒有用於它的上下文。 可是,能夠將存儲過程映射到方法並調用這些方法。 有關詳細信息,請參閱存儲過程

class FormatQuery
{
    static void Main()
    {            
        // 數據源
        double[] radii = { 1, 2, 3 };

        // 查詢表達式
        IEnumerable<string> query =
            from rad in radii
            select $"Area = {rad * rad * Math.PI:F2}";

        // 執行查詢
        foreach (string s in query)
            Console.WriteLine(s);

        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* 輸出:
    Area = 3.14
    Area = 12.57
    Area = 28.27
*/

其餘技術請參考

 

相關文章
相關標籤/搜索