Share via


使用 LINQ 轉換資料 (C#)

Language-Integrated Query (LINQ) 不只可以擷取資料, 它同時還是強大的資料轉換工具。 使用 LINQ 查詢,您可以使用來源序列做為輸入,並且用許多方式來修改來源序列,以建立新的輸出序列。 您可以修改序列,而不用修改項目將排序和群組。可能是 LINQ ,但是查詢最強的功能可能是建立新的。 這項作業是在 select 子句中完成。 例如,您可以進行下列工作:

  • 將多個輸入序列合併成具有新型別的單一輸出序列。

  • 建立輸出序列,其中的項目只由來源序列中每個項目的一個或多個屬性組成。

  • 建立輸出序列,其中的項目只由對來源資料執行作業後的結果組成。

  • 建立不同格式的輸出序列。 例如,您可以將資料從 SQL 資料列或文字檔轉換為 XML。

以下提供一些範例。 當然,這些轉換也可以用各種方式合併至相同查詢中。 甚至,某個查詢的輸出序列可以當成新查詢的輸入序列。

將多個輸入聯結成一個輸出序列

您可以使用 LINQ 查詢,建立項目來自多個輸入序列的輸出序列。 下列範例顯示如何合併兩個記憶體中資料結構,而相同的準則也適用於合併來自 XML 或 SQL 或 DataSet 來源的資料。 假設有下列兩個類別 (Class) 型別:

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; }
}

下列範例會顯示查詢:

class DataTransformations
{
    static void Main()
    {
        // Create the first data source.
        List<Student> students = new List<Student>()
        {
            new Student {First="Svetlana",
                Last="Omelchenko", 
                ID=111, 
                Street="123 Main Street",
                City="Seattle",
                Scores= new List<int> {97, 92, 81, 60}},
            new Student {First="Claire",
                Last="O’Donnell", 
                ID=112,
                Street="124 Main Street",
                City="Redmond",
                Scores= new List<int> {75, 84, 91, 39}},
            new Student {First="Sven",
                Last="Mortensen",
                ID=113,
                Street="125 Main Street",
                City="Lake City",
                Scores= new List<int> {88, 94, 65, 91}},
        };

        // Create the second data source.
        List<Teacher> teachers = new List<Teacher>()
        {                
            new Teacher {First="Ann", Last="Beebe", ID=945, City = "Seattle"},
            new Teacher {First="Alex", Last="Robinson", ID=956, City = "Redmond"},
            new Teacher {First="Michiyo", Last="Sato", ID=972, City = "Tacoma"}
        };

        // Create the query.
        var peopleInSeattle = (from student in students
                    where student.City == "Seattle"
                    select student.Last)
                    .Concat(from teacher in teachers
                            where teacher.City == "Seattle"
                            select teacher.Last);

        Console.WriteLine("The following students and teachers live in Seattle:");
        // Execute the query.
        foreach (var person in peopleInSeattle)
        {
            Console.WriteLine(person);
        }

        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    The following students and teachers live in Seattle:
    Omelchenko
    Beebe
 */

如需詳細資訊,請參閱join 子句 (C# 參考)select 子句 (C# 參考)

選取每個來源項目的子集

有兩種主要方式可以用來選取來源序列中每個項目的子集。

  1. 若只要選取來源項目的一個成員,請使用點運算。 在下列範例中,假設 Customer 物件含有多個公用 (Public) 屬性 (包括名為 City 的字串)。 執行時,這個查詢會產生字串的輸出序列。

    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};
    

如需詳細資訊,請參閱物件和集合初始設定式 (C# 程式設計手冊)匿名型別 (C# 程式設計手冊)

將記憶體中物件轉換為 XML

LINQ 查詢簡化了在記憶體中資料結構、SQL 資料庫、ADO.NET Dataset 和 XML 資料流或文件之間的資料轉換。 下列範例會將記憶體中資料結構內的物件轉換為 XML 項目。

class XMLTransform
{
    static void Main()
    {            
        // Create the data source by using a collection initializer.
        // The Student class was defined previously in this topic.
        List<Student> students = new List<Student>()
        {
            new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores = new List<int>{97, 92, 81, 60}},
            new Student {First="Claire", Last="O’Donnell", ID=112, Scores = new List<int>{75, 84, 91, 39}},
            new Student {First="Sven", Last="Mortensen", ID=113, Scores = new List<int>{88, 94, 65, 91}},
        };

        // Create the query.
        var studentsToXML = new XElement("Root",
            from student in students
            let x = String.Format("{0},{1},{2},{3}", student.Scores[0],
                    student.Scores[1], student.Scores[2], student.Scores[3])
            select new XElement("student",
                       new XElement("First", student.First),
                       new XElement("Last", student.Last),
                       new XElement("Scores", x)
                    ) // end "student"
                ); // end "Root"

        // Execute the query.
        Console.WriteLine(studentsToXML);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}

這個程式碼會產生下列 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>

如需詳細資訊,請參閱Creating XML Trees in C#

在來源項目上執行作業

輸出序列可能不會包含來源序列的任何項目或項目屬性。 輸出序列可能只是使用來源項目做為輸入引數計算而得的值序列。 下列簡單查詢在執行時會輸出字串序列,其中的值是根據 double 型別的來源項目序列計算而得的結果。

注意事項注意事項

如果查詢會轉譯為另一個領域,則不支援在查詢運算式中呼叫方法。例如,因為 SQL Server 沒有一般 C# 方法所需的內容,所以不可以在 LINQ to SQL 中呼叫一般 C# 方法。但可以將預存程序 (Stored Procedure) 對應至方法,再呼叫預存程序。如需詳細資訊,請參閱Stored Procedures: Mapping and Calling (LINQ to SQL)

class FormatQuery
{
    static void Main()
    {            
        // Data source.
        double[] radii = { 1, 2, 3 };

        // Query.
        IEnumerable<string> query =
            from rad in radii
            select String.Format("Area = {0}", (rad * rad) * 3.14);

        // Query execution. 
        foreach (string s in query)
            Console.WriteLine(s);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    Area = 3.14
    Area = 12.56
    Area = 28.26
*/

請參閱

工作

HOW TO:使用 Joins 以 LINQ 合併資料 (Visual Basic)

參考

select 子句 (C# 參考)

概念

LINQ 查詢運算式 (C# 程式設計手冊)

其他資源

LINQ (Language-Integrated Query)

LINQ to SQL

LINQ to DataSet

LINQ to XML