Exemplarische Vorgehensweise: Freigeben von Entitäten zwischen mehreren Domänendiensten

In der WCF RIA Services-Anwendung müssen Sie möglicherweise Daten aus einer Vielzahl von Datenquellen anzeigen oder eine Entität für mehr als einen Domänendienst verfügbar machen. Zum Beispiel muss eine E-Commerce-Website möglicherweise Daten aus dem Auftragsverarbeitungssystem in Produkte aus einem Drittanbieter-Domänendienst integrieren. RIA Services ermöglicht dieses Szenario, indem Verweise zwischen Entitäten von anderen DomainContext-Typen unterstützt werden. Weitere Informationen zu den Eigenschaften und Beschränkungen dieser Funktion finden Sie im Thema Gemeinsam verwendete Entitäten.

In dieser exemplarischen Vorgehensweise werden zwei verschiedene Methoden für die Definition einer Zuordnung zwischen Entitäten in unterschiedlichen Domänenkontextinstanzen vorgestellt:

  • Im ersten Teil wird die Zuordnung durch Hinzufügen von Code im Serverprojekt definiert.

  • Im zweiten Teil wird die Zuordnung mit Code im Clientprojekt definiert.

Bei beiden Methoden zur Definition der Zuordnung wird der gleiche Code auf dem Client verwendet, um die Daten abzurufen und anzuzeigen.

Zur Veranschaulichung werden in dieser exemplarischen Vorgehensweise zwei Entitätsmodelle und zwei Domänendienste für das Verfügbarmachen von Daten in der AdventureWorksLT-Beispieldatenbank erstellt. Normalerweise würden nicht zwei Entitätsmodelle und zwei Domänendienste erstellt werden, um Daten aus einer einzelnen Quelle verfügbar zu machen. Mit der hier erläuterten Methode wird das Beispiel vereinfacht. Gleichzeitig erfahren Sie, wie Sie mit komplexeren Szenarien umgehen, die mehrere Datenquellen umfassen. Ein anderes Beispiel zum Anzeigen von verknüpften Daten aus einer einzelnen Datenquelle finden Sie unter Exemplarische Vorgehensweise: Anzeigen von verwandten Daten in einer Silverlight-Geschäftsanwendung.

Erforderliche Komponenten

Für diese und die anderen exemplarischen Vorgehensweisen in der RIA Services -Dokumentation müssen zusätzlich zu WCF RIA Services und dem WCF RIA Services-Toolkit mehrere erforderliche Programme installiert und korrekt konfiguriert werden, z. B. Visual Studio 2010, die Silverlight Developer-Laufzeit und das Silverlight-SDK. Zudem müssen Sie SQL Server 2008 R2 Express with Advanced Services installieren und konfigurieren und die AdventureWorks OLTP- und LT-Datenbanken installieren.

Ausführliche Anweisungen für jede dieser erforderlichen Komponenten finden Sie in den Themen unter Erforderliche Komponenten für WCF RIA Services. Folgen Sie den Anweisungen in diesen Themen, bevor Sie mit dieser exemplarischen Vorgehensweise fortfahren, um sicherzustellen, dass beim Ausführen der exemplarischen Vorgehensweisen für RIA Services so wenig Probleme wie möglich auftreten.

Erstellen einer Projektmappe, der Datenmodelle und der Domänendienste

So richten Sie eine RIA Services-Projektmappe ein

  1. Erstellen Sie in Visual Studio 2010 ein neues RIA Services -Projekt, indem Sie Datei, Neu und dann Projekt auswählen.

    Das Dialogfeld Neues Projekt wird angezeigt.

  2. Wählen Sie aus den Silverlight-Vorlagen die Vorlage Silverlight-Anwendung aus, und nennen Sie das neue Projekt SharedEntityExample.

  3. Klicken Sie auf OK.

    Das Dialogfeld Neue Silverlight-Anwendung wird angezeigt.

  4. Aktivieren Sie das Kontrollkästchen WCF RIA Services aktivieren im unteren Bereich des Fensters.

  5. Klicken Sie auf OK, um die Projektmappe zu erstellen.

So erstellen Sie zwei Entity Data Models

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Serverprojekt (SharedEntityExample.Web), wählen Sie Hinzufügen und dann Neues Element aus.

    Das Dialogfeld Neues Element hinzufügen wird angezeigt.

  2. Wählen Sie links in der Liste Installierte Vorlagen die Option Daten aus, und wählen Sie anschließend die Vorlage ADO.NET Entity Data Model aus.

  3. Nennen Sie die neue Datei SalesModel.edmx, und klicken Sie anschließend auf Hinzufügen.

    Der Assistent für Entity Data Model wird angezeigt.

  4. Wählen Sie im Bildschirm Modellinhalt auswählen die Option Aus Datenbank generieren aus, und klicken Sie anschließend auf Weiter.

  5. Erstellen Sie im Bildschirm Wählen Sie Ihre Datenverbindung aus eine Datenverbindung mit der AdventureWorksLT-Datenbank.

  6. Wenn die AdventureWorksLT-Datenbank nicht in der Dropdownliste angezeigt wird, klicken Sie auf Neue Verbindung, und wählen Sie den richtigen Servernamen aus. Wählen Sie anschließend die AdventureWorksLT-Datenbank im Dropdownmenü im Feld Verbindung mit einer Datenbank herstellen im unteren Bereich des Fensters aus. Klicken Sie auf die Schaltfläche Verbindung testen, um sicherzustellen, dass auf die Datenbank zugegriffen werden kann, und klicken Sie auf OK.

  7. Stellen Sie sicher, dass das Kontrollkästchen Die Entitätsverbindungseinstellungen in Web.Config speichern als aktiviert wird, wenn Sie zum Assistenten für Entity Data Model zurückkehren und den Wert der Entitätsverbindungseinstellungen in Sales_DataEntities ändern.

  8. Klicken Sie auf Weiter.

  9. Wählen Sie auf dem Bildschirm Datenbankobjekte auswählen die Tabelle SalesOrderHeader aus.

  10. Klicken Sie auf Fertig stellen.

    Das Entitätsmodell wird für die Tabelle erstellt.

  11. Wiederholen Sie die vorherigen Schritte in diesem Abschnitt, um ein anderes Entity Data Model für die AdventureWorksLT-Datenbank zu erstellen, nennen Sie es jedoch CustomerModel.edmx. Ändern Sie nun den Wert der Entitätsverbindungseinstellung in "Web.config" in Customer_DataEntities, und wählen Sie die Tabelle Kunde (SalesLT) aus.

  12. Erstellen Sie die Projektmappe.

  13. Öffnen Sie die Codedatei für das Verkaufsentitätsmodell. Die SalesOrderHeader-Klasse verfügt über eine CustomerID-Eigenschaft. Sie verwenden diese Eigenschaft, um SalesOrderHeader und Customer zuzuordnen.

So erstellen Sie die Domänendienste

  1. Klicken Sie mit der rechten Maustaste auf das Projekt "SharedEntityExample.Web server", und wählen Sie Hinzufügen und Neues Element aus.

  2. Wählen Sie in der Liste der Kategorien Web aus, und wählen Sie dann die Vorlage Domänendienstklasse aus.

  3. Nennen Sie die Klasse SalesDomainService.cs (oder SalesDomainService.vb).

  4. Klicken Sie auf Hinzufügen.

    Das Dialogfeld Neue Domänendienstklasse hinzufügen wird angezeigt.

  5. Stellen Sie sicher, dass das Kontrollkästchen Clientzugriff aktivieren aktiviert wird.

  6. Wählen Sie in der Liste Verfügbare DataContext-/ObjectContext-Klassen das Datenkontextobjekt Sales_DataEntities (Entity Framework) aus.

    TipTipp:
    Wenn Sie der Datenverbindung beim Erstellen des Entitätsmodells einen anderen Namen geben, wählen Sie das Datenkontextobjekt aus, das die Entität SalesOrderHeader beinhaltet.
  7. Aktivieren Sie unter Entitäten das Kontrollkästchen für die Entität SalesOrderHeader.

  8. Klicken Sie auf OK.

    Dadurch wird die Domänendienstklasse generiert.

  9. Wiederholen Sie die vorherigen Schritte in diesem Abschnitt, um einen anderen Domänendienst zu erstellen, nennen Sie ihn jedoch CustomerDomainService.cs (oder CustomerDomainService.vb). Wählen Sie anschließend das Datenkontextobjekt Customer_DataEntities aus, und aktivieren Sie das Kontrollkästchen für die Entität Customer.

  10. Erstellen Sie die Projektmappe.

  11. Öffnen Sie im Clientprojekt im Ordner "Generated_Code" die generierte Codedatei "SharedEntityExample.Web.g.cs" (Sie müssen alle Objekte anzeigen, damit diese Datei, die standardmäßig ausgeblendet ist, sichtbar ist). Beachten Sie, dass es einen SalesDomainContext und einen CustomerDomainContext gibt. Sie laden die zugeordneten Daten mithilfe beider Domänenkontextobjekte.

  12. Schließen Sie die generierte Codedatei.

Definieren der Zuordnung zu Code im Serverprojekt

Sie verfügen derzeit über zwei separate Entitätsmodelle und zwei Domänendienste, von denen jeweils eine Entität verfügbar gemacht wird. Sie können Daten aus einer der beiden Entitäten gesondert laden, indem Sie den entsprechenden Domänendienst aufrufen. Um Daten zu laden, die eine Kombination der Daten aus beiden Entitäten darstellen, müssen Sie jedoch die Beziehung zwischen diesen Entitäten definieren. Die folgenden Schritte zeigen, wie diese Beziehung im Serverprojekt definiert wird.

So definieren Sie die Zuordnung im Serverprojekt

  1. Klicken Sie mit der rechten Maustaste auf das Serverprojekt, und wählen Sie Hinzufügen und Neues Element aus.

  2. Wählen Sie in der Liste der Kategorien Web aus, und wählen Sie dann die Vorlage Klasse aus.

  3. Nennen Sie die Klasse SalesOrderHeader.cs (oder SalesOrderHeader.vb), und klicken Sie dann auf Hinzufügen.

  4. Fügen Sie in der Klassendatei SalesOrderHeader der Klassendeklaration das Schlüsselwort partial hinzu.

    Partial Public Class SalesOrderHeader
    
    End Class
    
    namespace SharedEntityExample.Web
    {
        public partial class SalesOrderHeader
        {
        }
    }
    
  5. Fügen Sie eine Eigenschaft mit dem Namen Customer hinzu, die ein Objekt vom Typ Customer zurückgibt.

    Partial Public Class SalesOrderHeader
        Public Property Customer() As Customer
    
    End Class
    
    namespace SharedEntityExample.Web
    {
        public partial class SalesOrderHeader
        {
            public Customer Customer { get; set; }
        }
    }
    
  6. Fügen Sie eine using-Anweisung (oder Imports-Anweisung) für den System.ServiceModel.DomainServices-Namespace und den System.ComponentModel.DataAnnotations-Namespace hinzu.

  7. Fügen Sie der Customer-Eigenschaft das ExternalReferenceAttribute-Attribut hinzu.

  8. Fügen Sie der Customer-Eigenschaft das AssociationAttribute-Attribut mit den folgenden Werten hinzu.

    Imports System.ServiceModel.DomainServices
    Imports System.ComponentModel.DataAnnotations
    
    Partial Public Class SalesOrderHeader
        <ExternalReference()> _
        <Association("Sales_Customer", "CustomerID", "CustomerID")> _
        Public Property Customer() As Customer
    
    End Class
    
    using System;
    using System.ServiceModel.DomainServices;
    using System.ComponentModel.DataAnnotations;
    
    namespace SharedEntityExample.Web
    {
        public partial class SalesOrderHeader
        {
            [ExternalReference]
            [Association("Sales_Customer", "CustomerID", "CustomerID")]
            public Customer Customer { get; set; }
        }
    }
    
  9. Erstellen Sie die Projektmappe.

  10. Öffnen Sie im Clientprojekt im Ordner "Generated_Code" die generierte Codedatei, und beachten Sie, dass die SalesOrderHeader-Klasse jetzt eine Customer-Eigenschaft mit dem ExternalReferenceAttribute-Attribut und dem AssociationAttribute-Attribut enthält.

  11. Schließen Sie die generierte Codedatei.

Laden der Daten aus beiden Entitäten

Eigenschaften, die auf eine Entität aus einem anderen Domänenkontext verweisen, sind NULL, bis die Entität, auf die verwiesen wird, in ihren ursprünglichen Domänenkontext geladen wird. Die Entität, auf die verwiesen wird, wird nicht automatisch geladen. Sie müssen die Entität über den ursprünglichen Domänenkontext laden, bevor Sie auf Entität mit Querverweisen zugreifen.

So laden Sie die Daten von beiden Entitäten

  1. Öffnen Sie im Clientprojekt die Datei "MainPage.xaml".

  2. Ziehen Sie ein DataGrid-Steuerelement aus der Toolbox in das Grid-Element.

    Ein XML-Namespace und Verweise auf Datenassemblys werden hinzugefügt.

  3. Nennen Sie DataGridSalesGrid, und definieren Sie Spalten, in denen die kombinierten entsprechend der Darstellung im folgenden XAML angezeigt werden.

    <UserControl  x:Class="SharedEntityExample.MainPage"
        xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
    
        <Grid x:Name="LayoutRoot" Background="White">
            <data:DataGrid Name="SalesGrid" AutoGenerateColumns="False">
                <data:DataGrid.Columns>
                    <data:DataGridTextColumn Header="Sales Order ID" Binding="{Binding SalesOrderID}"></data:DataGridTextColumn>
                    <data:DataGridTextColumn Header="Total Due" Binding="{Binding TotalDue}"></data:DataGridTextColumn>
                    <data:DataGridTextColumn Header="Order Date" Binding="{Binding OrderDate}"></data:DataGridTextColumn>
                    <data:DataGridTextColumn Header="Customer First Name" Binding="{Binding Customer.FirstName}"></data:DataGridTextColumn>
                    <data:DataGridTextColumn Header="Last Name" Binding="{Binding Customer.LastName}"></data:DataGridTextColumn>
                </data:DataGrid.Columns>
            </data:DataGrid>
        </Grid>
    </UserControl>
    
  4. Öffnen Sie die CodeBehind-Datei "MainPage.xaml.cs" (oder "MainPage.xaml.vb").

  5. Fügen Sie eine using-Anweisung (oder eine Imports-Anweisung) für den SharedEntityExample.Web-Namespace und den System.ServiceModel.DomainServices.Client-Namespace hinzu.

  6. Erstellen Sie Variablen für Instanzen von SalesDomainContext und CustomerDomainContext.

    Private salesContext As New SalesDomainContext()
    Private customerContext As New CustomerDomainContext()
    
    private SalesDomainContext salesContext = new SalesDomainContext();
    private CustomerDomainContext customerContext = new CustomerDomainContext();
    
  7. Fügen Sie im Konstruktor zwischen den Domänenkontextobjekten durch Aufrufen der AddReference-Methode einen Verweis hinzu, laden Sie jede Entität durch Aufrufen der Load-Methode, und legen Sie die Verkaufsentitäten auf die ItemsSource von DataGrid fest.

    Imports SharedEntityExample.Web
    Imports System.ServiceModel.DomainServices.Client
    
    Partial Public Class MainPage
        Inherits UserControl
    
        Private salesContext As New SalesDomainContext()
        Private customerContext As New CustomerDomainContext()
    
        Public Sub New()
            InitializeComponent()
    
            salesContext.AddReference(GetType(Customer), customerContext)
    
            Dim salesLoadOp = salesContext.Load(salesContext.GetSalesOrderHeadersQuery())
            Dim customerLoadOp = customerContext.Load(customerContext.GetCustomersQuery())
    
            SalesGrid.ItemsSource = salesLoadOp.Entities
        End Sub
    
    End Class
    
    using System;
    using System.Windows.Controls;
    using SharedEntityExample.Web;
    using System.ServiceModel.DomainServices.Client;
    
    namespace SharedEntityExample
    {
        public partial class MainPage : UserControl
        {
            private SalesDomainContext salesContext = new SalesDomainContext();
            private CustomerDomainContext customerContext = new CustomerDomainContext();
    
            public MainPage()
            {
                InitializeComponent();
    
                salesContext.AddReference(typeof(Customer), customerContext);
    
                LoadOperation<SalesOrderHeader> salesLoadOp = salesContext.Load(salesContext.GetSalesOrderHeadersQuery());
                LoadOperation<Customer> customerLoadOp = customerContext.Load(customerContext.GetCustomersQuery());
    
                SalesGrid.ItemsSource = salesLoadOp.Entities;
            }
        }
    }
    
  8. Führen Sie die Projektmappe aus.

    Sie sehen eine DataGrid-Instanz, in der Daten aus zwei Entitäten in zwei separaten Entitätsmodellen und Domänendiensten anzeigt werden.

Definieren der Zuordnung zu Code im Clientprojekt

Sie können auch die Zuordnung zwischen den Entitäten auf dem Client definieren, ohne dem Serverprojekt Code hinzufügen zu müssen. Diese Methode wird empfohlen, wenn Sie keine neue Eigenschaft in dem Serverprojekt einführen möchten, dessen einziger Zweck darin besteht, dass die Daten gemeinsam angezeigt werden.

So definieren Sie die Zuordnung zu Code im Clientprojekt

  1. Löschen Sie im Serverprojekt die gesamte Datei "SalesOrderHeader.cs" (oder "SalesOrderHeader.vb"), die Sie zuvor hinzugefügt haben (oder kommentieren Sie die Datei aus).

  2. Erstellen Sie die Projektmappe, damit die generierte Codedatei nicht mehr über eine Customer-Eigenschaft auf dem SalesOrderHeader-Objekt verfügt.

  3. Fügen Sie im Clientprojekt eine neue Klassendatei mit dem Namen SalesOrderHeader.cs (oder SalesOrderHeader.vb) hinzu.

  4. Fügen Sie in der Klassendatei SalesOrderHeader der Klassendeklaration das Schlüsselwort partial hinzu, und ändern Sie den Namespace in SharedEntityExample.Web. (Wenn Sie Visual Basic verwenden, können Sie den Web-Namespace mit der Namespace-Anweisung angeben.)

    Diese Klasse erweitert die Klasse in der generierten Codedatei. Die generierte Entitätsklasse besitzt den Namespace aus dem Serverprojekt.

  5. Fügen Sie eine using-Anweisung (oder eine Imports-Anweisung für Visual Basic) für die folgenden Namespaces hinzu: System.ServiceModel.DomainServices, System.ServiceModel.DomainServices.Client und System.ComponentModel.DataAnnotations.

  6. Um die Zuordnung festzulegen, definieren Sie die Customer-Eigenschaft oder die SalesOrderHeader-Klasse, und markieren Sie sie mit dem ExternalReferenceAttribute-Attribut und dem AssociationAttribute-Attribut (wie im folgenden Codebeispiel gezeigt).

    Imports System.ServiceModel.DomainServices
    Imports System.ServiceModel.DomainServices.Client
    Imports System.ComponentModel.DataAnnotations
    
    Namespace Web
    
        Partial Public Class SalesOrderHeader
            Private _customer As EntityRef(Of Customer)
    
            <ExternalReference()> _
            <Association("Sales_Customer", "CustomerID", "CustomerID")> _
            Public ReadOnly Property Customer() As Customer
                Get
                    If (Me._customer Is Nothing) Then
                        Me._customer = New EntityRef(Of Customer)(Me, "Customer", AddressOf Me.FilterCustomer)
                    End If
    
                    Return Me._customer.Entity
                End Get
            End Property
    
            Private Function FilterCustomer(ByVal entity As Customer) As Boolean
                Return (entity.CustomerID = Me.CustomerID)
            End Function
        End Class
    
    End Namespace
    
    using System;
    using System.Windows.Controls;
    using System.ServiceModel.DomainServices;
    using System.ComponentModel.DataAnnotations;
    using System.ServiceModel.DomainServices.Client;
    
    namespace SharedEntityExample.Web
    {
        public partial class SalesOrderHeader
        {
            private EntityRef<Customer> _customer;
    
            [ExternalReference]
            [Association("Sales_Customer", "CustomerID", "CustomerID")]
            public Customer Customer
            {
                get
                {
                    if (this._customer == null)
                    {
                        this._customer = new EntityRef<Customer>(this, "Customer", this.FilterCustomer);
                    }
    
                    return this._customer.Entity;
                }
            }
    
            private bool FilterCustomer(Customer entity)
            {
                return (entity.CustomerID == this.CustomerID);
            }
        }
    }
    
  7. Drücken Sie F5, um die Projektmapppe auszuführen.

    Die DataGrid-Instanz, in der Daten angezeigt werden, die von jeder Entität in den zwei separaten Entitätsmodellen für ihre jeweiligen Domänendienste freigegeben wurden, wird jetzt im Browser angezeigt.