Condividi tramite


Procedura dettagliata: condivisione di entità tra più servizi del dominio

Nell'applicazione WCF RIA Services, potrebbe essere necessario visualizzare dati provenienti da una varietà di origini dati o esporre un'entità a più servizi del dominio. Potrebbe ad esempio essere necessario, in un sito Web di e-commerce, integrare i dati dal sistema di elaborazione degli ordini con i prodotti da un servizio del dominio di terze parti. RIA Services consente di realizzare questo scenario mediante il supporto di riferimenti tra entità di diversi tipi DomainContext. Per ulteriori informazioni sulla natura e sulle limitazioni di questa funzionalità, vedere l'argomento Entità condivise.

In questa procedura dettagliata, verranno illustrate due modalità diverse di definire un'associazione tra entità in istanze del contesto del dominio diverse:

  • Nella prima parte, l'associazione viene definita aggiungendo codice nel progetto server.

  • Nella seconda parte, l'associazione viene definita mediante codice nel progetto client.

Entrambi gli approcci alla definizione dell'utilizzo di associazione utilizzano lo stesso codice sul client per recuperare e visualizzare i dati.

A scopo illustrativo, in questa procedura dettagliata verranno creati due modelli di entità e due servizi del dominio per esporre i dati nel database di esempio AdventureWorksLT. In condizioni reali, non si creerebbero due modelli di entità e due servizi del dominio per esporre i dati da una singola origine. Questo approccio viene utilizzato per semplificare l'esempio e per apprendere la tecnica da adottare in scenari più complicati in cui vengono utilizzate più origini dati. Per un altro esempio di visualizzazione di dati correlati da una sola origine dati, vedere Procedura dettagliata: visualizzazione di dati correlati in un'applicazione aziendale di Silverlight.

Prerequisiti

Per l'esecuzione di questa e di altre procedure dettagliate descritte nella documentazione di RIA Services è necessario che siano installati e configurati correttamente alcuni programmi prerequisiti quali Visual Studio 2010 e Silverlight Developer Runtime e SDK, oltre a WCF RIA Services e a WCF RIA Services Toolkit. È inoltre richiesta l'installazione e la configurazione di SQL Server 2008 R2 Express with Advanced Services e l'installazione del database AdventureWorks OLTP e LT.

Le istruzioni dettagliate per soddisfare tali prerequisiti vengono fornite negli argomenti all'interno del nodo Prerequisiti per WCF RIA Services. Seguire tali istruzioni prima di continuare con questa procedura dettagliata in modo da assicurarsi che si verifichi il minor numero possibile di problemi durante l'esecuzione della procedura dettagliata di RIA Services .

Creazione di una soluzione, dei modelli di dati e dei servizi del dominio

Per impostare una soluzione Servizi RIA

  1. In Visual Studio 2010, creare un nuovo progetto RIA Services selezionando File, Nuovo, quindi Progetto.

    Verrà visualizzata la finestra di dialogo Nuovo progetto.

  2. Selezionare il modello Applicazione Silverlight dai modelli Silverlight e denominare il nuovo progetto SharedEntityExample.

  3. Fare clic su OK.

    Verrà visualizzata la finestra di dialogo Nuova applicazione Silverlight.

  4. Selezionare la casella di controllo Abilita WCF RIA Services nella parte inferiore della finestra.

  5. Fare clic su OK per creare la soluzione.

Per creare due modelli di dati di entità

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto server, (SharedEntityExample.Web), scegliere Aggiungi, quindi selezionare Nuovo elemento.

    Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.

  2. Scegliere Dati dall'elenco Modelli installati nella parte sinistra, quindi selezionare il modello ADO.NET Entity Data Model.

  3. Denominare il file SalesModel.edmx, quindi fare clic su Aggiungi.

    Viene visualizzata la procedura guidata Entity Data Model.

  4. Nella schermata Scegli contenuto Model fare clic su Genera da database, quindi su Avanti.

  5. Nella schermata Scegli la connessione dati creare una connessione al database AdventureWorksLT.

  6. Se il database AdventureWorksLT non è visualizzato nell'elenco a discesa, fare clic su Nuova connessione, selezionare il corretto Nome server, quindi selezionare la base dati di AdventureWorksLT dal menu a discesa nella casella Connessione al database nella parte inferiore della finestra. Selezionare il pulsante Test connessione per assicurarsi che il database sia accessibile e fare clic su OK.

  7. Verificare che sia selezionata la casella di controllo Salva impostazioni stringa di connessione entity in Web.Config come quando si torna alla Procedura guidata Entity Data Model e impostare il valore delle impostazioni di connessione dell'entità su Sales_DataEntities.

  8. Scegliere Avanti.

  9. Nella schermata Scegli oggetti di database selezionare la tabella SalesOrderHeader.

  10. Scegliere Fine.

    Viene creato il modello di entità per la tabella.

  11. Ripetere i passaggi precedenti in questa sezione per creare un altro Entity Data Model per il database AdventureWorksLT, ma denominandolo CustomerModel.edmx, impostare il valore dell'impostazione di connessione dell'entità in Web.config su Customer_DataEntities e selezionare la tabella Customer (SalesLT).

  12. Compilare la soluzione.

  13. Aprire il file di codice per il modello di entità Sales e notare che la classe SalesOrderHeader dispone di una proprietà CustomerID. Si utilizzerà questa proprietà per associare SalesOrderHeader e Customer.

Per creare i servizi del dominio

  1. Fare clic con il pulsante destro del mouse sul progetto server SharedEntityExample.Web e scegliere Aggiungi, quindi Nuovo elemento.

  2. Nell'elenco delle categorie, scegliere Web, quindi selezionare il modello Classe di DomainService.

  3. Denominare la classe SalesDomainService.cs (o SalesDomainService.vb).

  4. Fare clic su Aggiungi.

    Verrà visualizzata la finestra di dialogo Aggiungi una nuova classe DomainService.

  5. Verificare che sia selezionata la casella di controllo Abilita l'accesso client.

  6. Dall'elenco Classi DataContext/ObjectContext disponibili, selezionare Sales_DataEntities (Entity Framework).

    TipSuggerimento:
    Se si è fornito alla connessione dati un nome diverso al momento di creare il modello di entità, selezionare l'oggetto contesto dati che contiene l'entità SalesOrderHeader.
  7. In Entità, selezionare la casella di controllo dell'entità SalesOrderHeader.

  8. Fare clic su OK.

    Ciò consente di generare la classe del servizio del dominio.

  9. Ripetere i passaggi precedenti in questa sezione per creare un altro servizio del dominio, ma denominandolo CustomerDomainService.cs (o CustomerDomainService.vb), selezionare l'oggetto contesto dati Customer_DataEntities e selezionare la casella di controllo dell'entità Customer.

  10. Compilare la soluzione.

  11. Nel progetto client, nella cartella Generated_Code, aprire il file di codice generato SharedEntityExample.Web.g.cs (sarà necessario visualizzare tutto il contenuto per vedere questo file, che è nascosto per impostazione predefinita) e notare la presenza degli oggetti SalesDomainContext e CustomerDomainContext. Si utilizzeranno entrambi oggetti di contesto del dominio per caricare i dati associati.

  12. Chiudere il file di codice generato.

Definizione dell'associazione con il codice nel progetto server

A questo punto si dispone di due modelli di entità separati e due servizi del dominio, di cui ognuno espone un'entità. È possibile caricare separatamente dati da qualsiasi entità chiamando il servizio del dominio appropriato. Tuttavia, per caricare dati che sono una combinazione di dati da entrambe le entità, è necessario definire la relazione tra tali entità. Nei passaggi seguenti viene mostrato come definire tale relazione nel progetto server.

Per definire l'associazione con il progetto server

  1. Fare clic con il pulsante destro del mouse sul progetto server, scegliere Aggiungi, quindi Nuovo elemento.

  2. Nell'elenco delle categorie, scegliere Web, quindi selezionare il modello Classe.

  3. Denominare la classe SalesOrderHeader.cs (o SalesOrderHeader.vb), quindi fare clic su Aggiungi.

  4. Nel file di classe SalesOrderHeader, aggiungere la parola chiave partial alla dichiarazione di classe.

    Partial Public Class SalesOrderHeader
    
    End Class
    
    namespace SharedEntityExample.Web
    {
        public partial class SalesOrderHeader
        {
        }
    }
    
  5. Aggiungere una proprietà denominata Customer che restituisce un oggetto del tipo Customer.

    Partial Public Class SalesOrderHeader
        Public Property Customer() As Customer
    
    End Class
    
    namespace SharedEntityExample.Web
    {
        public partial class SalesOrderHeader
        {
            public Customer Customer { get; set; }
        }
    }
    
  6. Aggiungere un'istruzione using (o Imports) per gli spazi dei nomi System.ServiceModel.DomainServices e System.ComponentModel.DataAnnotations.

  7. Aggiungere l'attributo ExternalReferenceAttribute alla proprietà Customer.

  8. Aggiungere l'attributo AssociationAttribute alla proprietà Customer con i valori seguenti.

    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. Compilare la soluzione.

  10. Nel progetto client, nella cartella Generated_Code, aprire il file del codice generato e notare che la classe SalesOrderHeader contiene ora una proprietà Customer con gli attributi ExternalReferenceAttribute e AssociationAttribute.

  11. Chiudere il file di codice generato.

Caricamento dei dati da entrambe le entità

Le proprietà che fanno riferimento a un'entità da un altro contesto del dominio risulteranno null fino a quando l'entità a cui si fa riferimento non verrà caricata nel contesto del dominio originale. L'entità a cui si fa riferimento non viene caricata automaticamente. È necessario caricare l'entità tramite il contesto del dominio dell'origine prima di accedere all'entità cui è stato fatto riferimento.

Per caricare i dati da entrambe le entità

  1. Nel progetto client, aprire il file MainPage.xaml.

  2. Dalla casella degli strumenti, trascinare un controllo DataGrid nell'elemento Grid.

    Vengono aggiunti uno spazio dei nomi XML e i riferimenti agli assembly di dati.

  3. Denominare DataGridSalesGrid e definire colonne per visualizzare i dati combinati come mostrato nel codice XAML seguente.

    <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. Aprire il file code-behind MainPage.xaml.cs (o MainPage.xaml.vb).

  5. Aggiungere un'istruzione using (o Imports) per gli spazi dei nomi SharedEntityExample.Web e System.ServiceModel.DomainServices.Client.

  6. Creare variabili per le istanze degli oggetti SalesDomainContext e CustomerDomainContext.

    Private salesContext As New SalesDomainContext()
    Private customerContext As New CustomerDomainContext()
    
    private SalesDomainContext salesContext = new SalesDomainContext();
    private CustomerDomainContext customerContext = new CustomerDomainContext();
    
  7. Nel costruttore, aggiungere un riferimento tra gli oggetti di contesto del dominio chiamando il metodo AddReference, caricare ogni entità chiamando il metodo Load e impostare le entità delle vendite sull'oggetto ItemsSource di DataGrid.

    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. Eseguire la soluzione.

    Sarà visibile un'istanza DataGrid in cui vengono visualizzati dati da due entità in due modelli di entità e servizi del dominio separati.

Definizione dell'associazione con il codice nel progetto client

È possibile definire anche l'associazione tra le entità sul client, senza dover aggiungere codice al progetto server. Questo approccio è migliore se si preferisce non introdurre una nuova proprietà nel progetto server il cui solo scopo è raggiungere l'obiettivo del client di visualizzare i dati in modo congiunto.

Per definire l'associazione con il codice nel progetto client

  1. Nel progetto server, eliminare (o impostare come commento) l'intero file SalesOrderHeader.cs (o SalesOrderHeader.vb) aggiunto in precedenza.

  2. Compilare la soluzione in modo che il file di codice generato non disponga più di una proprietà Customer sull'oggetto SalesOrderHeader.

  3. Nel progetto client, aggiungere un nuovo file di classe denominato SalesOrderHeader.cs (o SalesOrderHeader.vb).

  4. Nel file di classe SalesOrderHeader, aggiungere la parola chiave partial alla dichiarazione e modificare lo spazio dei nomi in SharedEntityExample.Web. Se si utilizza Visual Basic, è possibile specificare lo spazio dei nomi Web utilizzando l'istruzione Namespace.

    Questa classe consente di estendere la classe nel file di codice generato. La classe dell'identità generata dispone dello spazio dei nomi dal progetto server.

  5. Aggiungere un'istruzione using (o Imports per Visual Basic) per gli spazi dei nomi System.ServiceModel.DomainServices, System.ServiceModel.DomainServices.Client e System.ComponentModel.DataAnnotations.

  6. Per stabilire l'associazione, definire la proprietà Customer o la classe SalesOrderHeader e contrassegnarla con gli attributi ExternalReferenceAttribute e AssociationAttribute come mostrato nell'esempio di codice seguente.

    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. Premere F5 per eseguire la soluzione.

    L'istanza DataGrid che visualizza i dati condivisi all'esterno, da ognuna delle entità nei due modelli di entità separati nei rispettivi servizi del dominio, dovrebbe essere ora visualizzata nel browser.