Datentransformationen mit LINQ (C#)Data Transformations with LINQ (C#)

Bei Language-Integrated Query (LINQ)Language-Integrated Query (LINQ) geht es nicht nur um das Abrufen von Daten.Language-Integrated Query (LINQ)Language-Integrated Query (LINQ) is not only about retrieving data. Es ist auch ein leistungsstarkes Tool zur Datentransformation.It is also a powerful tool for transforming data. Mithilfe einer LINQLINQ-Abfrage können Sie eine Quellsequenz als Eingabe verwenden und sie auf viele Arten zum Erstellen einer neuen Ausgabesequenz ändern.By using a LINQLINQ query, you can use a source sequence as input and modify it in many ways to create a new output sequence. Sie können die Sequenz selbst durch Sortieren und Gruppieren ändern, ohne die Elemente zu ändern.You can modify the sequence itself without modifying the elements themselves by sorting and grouping. Aber das vielleicht leistungsstärkste Feature von LINQLINQ-Abfragen ist die Fähigkeit, neue Typen zu erstellen.But perhaps the most powerful feature of LINQLINQ queries is the ability to create new types. Dies erfolgt in der select-Klausel.This is accomplished in the select clause. Sie können z. B. folgende Aufgaben ausführen:For example, you can perform the following tasks:

  • Führen Sie mehrere Eingabesequenzen in einer einzelnen Ausgabesequenz, die einen neuen Typ hat, zusammen.Merge multiple input sequences into a single output sequence that has a new type.

  • Erstellen Sie Ausgabesequenzen, deren Elemente aus nur einer oder mehreren Eigenschaften jedes Elements in der Quellsequenz bestehen.Create output sequences whose elements consist of only one or several properties of each element in the source sequence.

  • Erstellen Sie Ausgabesequenzen, deren Elemente aus Ergebnissen der Vorgänge für die Quelldaten bestehen.Create output sequences whose elements consist of the results of operations performed on the source data.

  • Erstellen Sie Ausgabesequenzen in einem anderen Format.Create output sequences in a different format. Beispielsweise können Sie Daten aus SQL-Zeilen oder Textdateien in XML umwandeln.For example, you can transform data from SQL rows or text files into XML.

Dies sind nur einige Beispiele.These are just several examples. Natürlich können diese Transformationen auf verschiedene Weise in der gleichen Abfrage kombiniert werden.Of course, these transformations can be combined in various ways in the same query. Darüber hinaus kann die Ausgabesequenz einer Abfrage als Eingabesequenz für eine neue Abfrage verwendet werden.Furthermore, the output sequence of one query can be used as the input sequence for a new query.

Verknüpfen mehrerer Eingaben in eine AusgabesequenzJoining Multiple Inputs into One Output Sequence

Sie können eine LINQLINQ-Abfrage verwenden, um eine Ausgabesequenz zu erstellen, die Elemente von mehr als einer Eingabesequenz enthält.You can use a LINQLINQ query to create an output sequence that contains elements from more than one input sequence. Im folgenden Beispiel wird gezeigt, wie zwei Datenstrukturen im Arbeitsspeicher kombiniert werden können, aber die gleichen Prinzipien können angewendet werden, um Daten von XML- oder SQL- oder DataSet-Quellen zu kombinieren.The following example shows how to combine two in-memory data structures, but the same principles can be applied to combine data from XML or SQL or DataSet sources. Nehmen Sie die beiden folgenden Klassentypen an:Assume the following two class types:

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

Das folgende Beispiel gibt die Abfrage an:The following example shows the query:

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
 */

Weitere Informationen finden Sie unter join-Klausel und select-Klausel.For more information, see join clause and select clause.

Auswählen einer Teilmenge jedes QuellelementsSelecting a Subset of each Source Element

Es gibt zwei Hauptmethoden, eine Teilmenge jedes Elements in der Quellsequenz auszuwählen:There are two primary ways to select a subset of each element in the source sequence:

  1. Um nur einen Member des Quellelements auszuwählen, verwenden Sie die Punktoperation.To select just one member of the source element, use the dot operation. Im folgenden Beispiel wird angenommen, dass ein Customer-Objekt verschiedene öffentliche Eigenschaften enthält, einschließlich der Zeichenfolge City.In the following example, assume that a Customer object contains several public properties including a string named City. Bei der Ausführung erzeugt diese Abfrage eine Ausgabesequenz von Zeichenfolgen.When executed, this query will produce an output sequence of strings.

    var query = from cust in Customers  
                select cust.City;  
    
  2. Zum Erstellen von Elementen, die mehr als eine Eigenschaft aus dem Quellelement enthalten, können Sie einen Objektinitialisierer mit einem benannten Objekt oder einen anonymen Typ verwenden.To create elements that contain more than one property from the source element, you can use an object initializer with either a named object or an anonymous type. Das folgende Beispiel zeigt die Verwendung eines anonymen Typs zum Kapseln zweier Eigenschaften von jedem Customer-Element:The following example shows the use of an anonymous type to encapsulate two properties from each Customer element:

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

Weitere Informationen finden Sie unter Objekt- und Auflistungsinitialisierer und Anonyme Typen.For more information, see Object and Collection Initializers and Anonymous Types.

Transformieren von Objekten im Speicher in XMLTransforming in-Memory Objects into XML

LINQLINQ-Abfragen machen es einfacher, Daten zwischen Datenstrukturen im Speicher, SQL-Datenbanken, ADO.NETADO.NET-Datasets und XML-Streams oder XML-Dokumenten zu transformieren. queries make it easy to transform data between in-memory data structures, SQL databases, ADO.NETADO.NET Datasets and XML streams or documents. Im folgenden Beispiel werden Objekte in einer Datenstruktur im Arbeitsspeicher in XML-Elemente transformiert.The following example transforms objects in an in-memory data structure into XML elements.

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

Der Code erzeugt die folgende XML-Ausgabe:The code produces the following XML output:

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

Weitere Informationen finden Sie unter Erstellen von XML-Strukturen in C# (LINQ to XML).For more information, see Creating XML Trees in C# (LINQ to XML).

Ausführen von Operationen für QuellelementePerforming Operations on Source Elements

Eine Ausgabesequenz enthält möglicherweise keine Elemente oder Elementeigenschaften aus der Quellsequenz.An output sequence might not contain any elements or element properties from the source sequence. Die Ausgabe kann möglicherweise stattdessen eine Sequenz von Werten enthalten, die durch Verwendung der Quellelemente als Eingabeargumente berechnet wird.The output might instead be a sequence of values that is computed by using the source elements as input arguments. Die folgende einfache Abfrage gibt, wenn sie ausgeführt wird, eine Sequenz von Zeichenfolgen aus, deren Werte eine Berechnung basierend auf der Quellsequenz der Elemente des Typs double darstellen.The following simple query, when it is executed, outputs a sequence of strings whose values represent a calculation based on the source sequence of elements of type double.

Hinweis

Aufrufen von Methoden in Abfrageausdrücken wird nicht unterstützt, wenn die Abfrage in eine andere Domäne übersetzt wird.Calling methods in query expressions is not supported if the query will be translated into some other domain. Sie können beispielsweise keine normale C#-Methode in LINQ to SQLLINQ to SQL aufrufen, da SQL Server über keinen Kontext dafür verfügt.For example, you cannot call an ordinary C# method in LINQ to SQLLINQ to SQL because SQL Server has no context for it. Sie können jedoch gespeicherte Prozeduren Methoden zuordnen und diese aufrufen.However, you can map stored procedures to methods and call those. Weitere Informationen finden Sie unter Gespeicherte Prozeduren.For more information, see Stored Procedures.

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
*/

Siehe auchSee Also

Language-Integrated Query (LINQ) (C#) (Language-Integrated Query (LINQ) (C#))Language-Integrated Query (LINQ) (C#)
LINQ to SQLLINQ to SQL
LINQ to DataSetLINQ to DataSet
LINQ to XML (C#)LINQ to XML (C#)
LINQ-AbfrageausdrückeLINQ Query Expressions
select-Klauselselect clause