Vorgehensweise: Verknüpfen von zwei Auflistungen (LINQ to XML) (C#)How to: Join Two Collections (LINQ to XML) (C#)

Ein Element oder Attribut in einem XML-Dokument kann mitunter auf ein anderes Element oder Attribut verweisen.An element or attribute in an XML document can sometimes refer to another element or attribute. So enthält das XML-Dokument in Beispiel-XML-Datei: Kunden und Bestellungen (LINQ to XML) z.B. eine Liste von Kunden und eine Liste von Aufträgen.For example, the Sample XML File: Customers and Orders (LINQ to XML) XML document contains a list of customers and a list of orders. Jedes Customer-Element enthält ein CustomerID-Attribut.Each Customer element contains a CustomerID attribute. Jedes Order-Element enthält ein CustomerID-Element.Each Order element contains a CustomerID element. Das CustomerID-Element eines Auftrags verweist auf das CustomerID-Attribut eines Kunden.The CustomerID element in each order refers to the CustomerID attribute in a customer.

Das Thema Beispiel-XSD-Datei: Kunden und Bestellungen enthält ein XSD-Schema, das zum Validieren dieses Dokuments verwendet werden kann.The topic Sample XSD File: Customers and Orders contains an XSD that can be used to validate this document. Mit den Funktionen xs:key und xs:keyref des XSD-Schemas wird geprüft, ob das CustomerID-Attribut des Customer-Elements ein Schlüssel ist. Außerdem wird damit eine Beziehung zwischen dem CustomerID-Element in jedem Order-Element und dem CustomerID-Attribut in jedem Customer-Element hergestellt.It uses the xs:key and xs:keyref features of XSD to establish that the CustomerID attribute of the Customer element is a key, and to establish a relationship between the CustomerID element in each Order element and the CustomerID attribute in each Customer element.

Mit LINQ to XMLLINQ to XML können Sie diese Beziehung durch Verwenden der join-Klausel nutzen.With LINQ to XMLLINQ to XML, you can take advantage of this relationship by using the join clause.

Da es keinen Index gibt, führt eine solche Verknüpfung zu einer schlechten Laufzeitleistung.Note that because there is no index available, such joining will have poor runtime performance.

Ausführlichere Informationen zu join finden Sie unter Join Operations (C#) (Verknüpfungsvorgänge (C#)).For more detailed information about join, see Join Operations (C#).

BeispielExample

Das folgende Beispiel verknüpft die Customer-Elemente mit den Order-Elementen und generiert ein neues XML-Dokument, das das CompanyName-Element der Aufträge enthält.The following example joins the Customer elements to the Order elements, and generates a new XML document that includes the CompanyName element in the orders.

Vor dem Ausführen der Abfrage überprüft das Beispiel, ob das Dokument dem Schema in Beispiel-XSD-Datei: Kunden und Bestellungen entspricht.Before executing the query, the example validates that the document complies with the schema in Sample XSD File: Customers and Orders. Auf diese Weise wird sichergestellt, dass die JOIN-Klausel immer funktioniert.This ensures that the join clause will always work.

Diese Abfrage ruft zuerst alle Customer-Elemente ab und verknüpft sie dann mit den Order-Elementen.This query first retrieves all Customer elements, and then joins them to the Order elements. Sie wählt dabei nur die Aufträge der Kunden aus, deren CustomerID größer als "K" ist.It selects only the orders for customers with a CustomerID greater than "K". Anschließend projiziert die Abfrage ein neues Order-Element, das die Kundeninformationen in den einzelnen Aufträgen enthält.It then projects a new Order element that contains the customer information within each order.

In diesem Beispiel wird das folgende XML-Dokument verwendet: Beispiel-XML-Datei: Kunden und Bestellungen (LINQ to XML).This example uses the following XML document: Sample XML File: Customers and Orders (LINQ to XML).

In diesem Beispiel wird das folgende XML-Schema verwendet: Beispiel-XML-Datei: Kunden und Bestellungen (LINQ to XML).This example uses the following XSD schema: Sample XSD File: Customers and Orders.

Beachten Sie, dass diese Art von Verknüpfungen zu Leistungseinbußen führt.Note that joining in this fashion will not perform very well. Joins (Verknüpfungen) werden über eine lineare Suche ausgeführt.Joins are performed via a linear search. Es gibt keine Hashtabellen oder Indizes, die die Geschwindigkeit erhöhen könnten.There are no hash tables or indexes to help with performance.

XmlSchemaSet schemas = new XmlSchemaSet();  
schemas.Add("", "CustomersOrders.xsd");  

Console.Write("Attempting to validate, ");  
XDocument custOrdDoc = XDocument.Load("CustomersOrders.xml");  

bool errors = false;  
custOrdDoc.Validate(schemas, (o, e) =>  
                     {  
                         Console.WriteLine("{0}", e.Message);  
                         errors = true;  
                     });  
Console.WriteLine("custOrdDoc {0}", errors ? "did not validate" : "validated");  

if (!errors)  
{  
    // Join customers and orders, and create a new XML document with  
    // a different shape.  

    // The new document contains orders only for customers with a  
    // CustomerID > 'K'  
    XElement custOrd = custOrdDoc.Element("Root");  
    XElement newCustOrd = new XElement("Root",  
        from c in custOrd.Element("Customers").Elements("Customer")  
        join o in custOrd.Element("Orders").Elements("Order")  
                   on (string)c.Attribute("CustomerID") equals  
                      (string)o.Element("CustomerID")  
        where ((string)c.Attribute("CustomerID")).CompareTo("K") > 0  
        select new XElement("Order",  
            new XElement("CustomerID", (string)c.Attribute("CustomerID")),  
            new XElement("CompanyName", (string)c.Element("CompanyName")),  
            new XElement("ContactName", (string)c.Element("ContactName")),  
            new XElement("EmployeeID", (string)o.Element("EmployeeID")),  
            new XElement("OrderDate", (DateTime)o.Element("OrderDate"))  
        )  
    );  
    Console.WriteLine(newCustOrd);  
}  

Dieser Code erzeugt die folgende Ausgabe:This code produces the following output:

Attempting to validate, custOrdDoc validated  
<Root>  
  <Order>  
    <CustomerID>LAZYK</CustomerID>  
    <CompanyName>Lazy K Kountry Store</CompanyName>  
    <ContactName>John Steel</ContactName>  
    <EmployeeID>1</EmployeeID>  
    <OrderDate>1997-03-21T00:00:00</OrderDate>  
  </Order>  
  <Order>  
    <CustomerID>LAZYK</CustomerID>  
    <CompanyName>Lazy K Kountry Store</CompanyName>  
    <ContactName>John Steel</ContactName>  
    <EmployeeID>8</EmployeeID>  
    <OrderDate>1997-05-22T00:00:00</OrderDate>  
  </Order>  
  <Order>  
    <CustomerID>LETSS</CustomerID>  
    <CompanyName>Let's Stop N Shop</CompanyName>  
    <ContactName>Jaime Yorres</ContactName>  
    <EmployeeID>1</EmployeeID>  
    <OrderDate>1997-06-25T00:00:00</OrderDate>  
  </Order>  
  <Order>  
    <CustomerID>LETSS</CustomerID>  
    <CompanyName>Let's Stop N Shop</CompanyName>  
    <ContactName>Jaime Yorres</ContactName>  
    <EmployeeID>8</EmployeeID>  
    <OrderDate>1997-10-27T00:00:00</OrderDate>  
  </Order>  
  <Order>  
    <CustomerID>LETSS</CustomerID>  
    <CompanyName>Let's Stop N Shop</CompanyName>  
    <ContactName>Jaime Yorres</ContactName>  
    <EmployeeID>6</EmployeeID>  
    <OrderDate>1997-11-10T00:00:00</OrderDate>  
  </Order>  
  <Order>  
    <CustomerID>LETSS</CustomerID>  
    <CompanyName>Let's Stop N Shop</CompanyName>  
    <ContactName>Jaime Yorres</ContactName>  
    <EmployeeID>4</EmployeeID>  
    <OrderDate>1998-02-12T00:00:00</OrderDate>  
  </Order>  
</Root>  

Siehe auchSee Also

Erweiterte Abfragetechniken (LINQ to XML) (C#)Advanced Query Techniques (LINQ to XML) (C#)