다음을 통해 공유


연습: 여러 도메인 서비스 간 엔터티 공유

WCF RIA Services 응용 프로그램에서 다양한 데이터 소스의 데이터를 표시하거나 둘 이상의 도메인 서비스에 엔터티를 노출해야 할 수 있습니다. 예를 들어 전자 상거래 웹 사이트는 주문 처리 시스템의 데이터를 타사 도메인 서비스의 제품과 통합해야 할 수 있습니다. RIA Services 를 사용하면 서로 다른 DomainContext 형식의 엔터티 간 참조를 지원하여 이 시나리오를 가능하게 할 수 있습니다. 이 기능의 특성과 제한에 대한 자세한 내용은 공유 엔터티 항목을 참조하십시오.

이 연습에서는 서로 다른 도메인 컨텍스트 인스턴스의 엔터티 간에 연결을 정의하는 두 가지 방법을 보여 줍니다.

  • 첫 번째 부분에서는 서버 프로젝트에서 코드를 추가하여 연결을 정의합니다.

  • 두 번째 부분에서는 클라이언트 프로젝트에서 코드를 사용하여 연결을 정의합니다.

연결을 정의하는 두 방법 모두 클라이언트에서 동일한 코드를 사용하여 데이터를 검색하고 표시합니다.

이 연습에서 설명을 위해 AdventureWorksLT 샘플 데이터베이스에서 데이터를 노출하는 데 사용할 두 엔터티 모델과 두 도메인 서비스를 만듭니다. 일반적으로 단일 소스의 데이터를 노출하기 위해 두 엔터티 모델과 두 도메인 서비스를 만들지는 않습니다. 여러 데이터 소스를 채택하는 보다 복잡한 시나리오에서 사용할 수 있는 기법을 배우는 동안 예제를 단순화하기 위해 여기에서는 이 방법을 사용합니다. 단일 데이터 소스의 관련 데이터를 표시하는 또 다른 예제를 보려면 연습: Silverlight 비즈니스 응용 프로그램에서 관련 데이터 표시를 참조하십시오.

필수 구성 요소

RIA Services 설명서에서 제공하는 이 연습 및 다른 연습을 실행하려면 WCF RIA Services 및 WCF RIA Services 도구 키트 외에도 Visual Studio 2010, Silverlight Developer 런타임 및 SDK 등의 몇 가지 필수 구성 요소 프로그램을 올바르게 설치하고 구성해야 합니다. 또한 SQL Server 2008 R2 Express with Advanced Services를 설치하고 구성해야 하며 AdventureWorks OLTP 및 LT 데이터베이스를 설치해야 합니다.

이러한 각 사전 요구 사항을 충족하기 위한 자세한 지침은 WCF RIA Services의 사전 요구 사항 노드의 항목에서 제공합니다. 이 RIA Services 연습을 수행할 때 발생할 수 있는 문제를 최소화하려면 이 연습을 진행하기 전에 여기서 제공하는 지침을 따르십시오.

솔루션, 데이터 모델 및 도메인 서비스 만들기

RIA Services 솔루션을 설정하려면

  1. Visual Studio 2010에서 파일, 새로 만들기, 프로젝트를 차례로 선택하여 새 RIA Services 프로젝트를 만듭니다.

    새 프로젝트 대화 상자가 나타납니다.

  2. Silverlight 템플릿에서 Silverlight 응용 프로그램 템플릿을 선택하고 새 프로젝트의 이름을 SharedEntityExample로 지정합니다.

  3. 확인을 클릭합니다.

    새 Silverlight 응용 프로그램 대화 상자가 나타납니다.

  4. 창 아래쪽에서 WCF RIA Services 사용 확인란을 선택합니다.

  5. 확인을 클릭하여 솔루션을 만듭니다.

두 엔터티 데이터 모델을 만들려면

  1. 솔루션 탐색기에서 서버 프로젝트(SharedEntityExample.Web)를 마우스 오른쪽 단추로 클릭하고 추가를 선택한 다음 새 항목을 선택합니다.

    새 항목 추가 대화 상자가 나타납니다.

  2. 왼쪽의 설치된 템플릿 목록에서 데이터를 선택한 다음 ADO.NET 엔터티 데이터 모델 템플릿을 선택합니다.

  3. 새 파일의 이름을 SalesModel.edmx로 지정하고 추가를 클릭합니다.

    엔터티 데이터 모델 마법사가 나타납니다.

  4. 모델 콘텐츠 선택 화면에서 데이터베이스에서 생성을 선택하고 다음을 클릭합니다.

  5. 데이터 연결 선택 화면에서 AdventureWorksLT 데이터베이스에 대한 데이터 연결을 만듭니다.

  6. AdventureWorksLT 데이터베이스가 드롭다운 목록에 나타나지 않으면 새 연결을 클릭하고 올바른 서버 이름을 선택한 다음 창 아래쪽에 있는 데이터베이스에 연결 상자의 드롭다운 메뉴에서 AdventureWorksLT 데이터베이스를 선택합니다. 연결 테스트 단추를 선택하여 데이터베이스에 액세스할 수 있는지 확인하고 확인을 클릭합니다.

  7. 엔터티 데이터 모델 마법사로 돌아오면 다른 이름으로 Web.Config의 entity 연결 설정 저장 확인란이 선택되어 있는지 확인하고 entity 연결 설정의 값을 Sales_DataEntities로 변경합니다.

  8. 다음을 클릭합니다.

  9. 데이터베이스 개체 선택 화면에서 SalesOrderHeader 테이블을 선택합니다.

  10. 마침을 클릭합니다.

    엔터티 모델이 테이블에 대해 만들어집니다.

  11. 이 단원의 이전 단계를 반복하여 AdventureWorksLT 데이터베이스의 다른 엔터티 데이터 모델을 만들되 이름을 CustomerModel.edmx로 지정하고 Web.config의 entity 연결 설정 값을 Customer_DataEntities로 변경한 다음 Customer (SalesLT) 테이블을 선택합니다.

  12. 솔루션을 빌드합니다.

  13. Sales 엔터티 모델의 코드 파일을 열고 SalesOrderHeader 클래스에 CustomerID 속성이 있음을 확인합니다. 이 속성을 사용하여 SalesOrderHeaderCustomer를 연결하게 됩니다.

도메인 서비스를 만들려면

  1. SharedEntityExample.Web 서버 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가새 항목을 선택합니다.

  2. 범주 목록에서 을 선택한 다음 도메인 서비스 클래스 템플릿을 선택합니다.

  3. 클래스의 이름을 SalesDomainService.cs(또는 SalesDomainService.vb)로 지정합니다.

  4. 추가를 클릭합니다.

    새 도메인 서비스 클래스 추가 대화 상자가 나타납니다.

  5. 클라이언트 액세스 사용 확인란이 선택되어 있는지 확인합니다.

  6. 사용 가능한 DataContext/ObjectContext 클래스 목록에서 Sales_DataEntities (Entity Framework) 데이터 컨텍스트 개체를 선택합니다.

    Tip팁:
    엔터티 모델을 만들 때 데이터 연결에 다른 이름을 지정한 경우 SalesOrderHeader 엔터티가 포함된 데이터 컨텍스트 개체를 선택합니다.
  7. 엔터티 아래에서 SalesOrderHeader 엔터티 확인란을 선택합니다.

  8. 확인을 클릭합니다.

    도메인 서비스 클래스가 생성됩니다.

  9. 이 단원의 이전 단계를 반복하여 다른 도메인 서비스를 만들되 이름을 CustomerDomainService.cs(또는 CustomerDomainService.vb)로 지정하고 Customer_DataEntities 데이터 컨텍스트 개체를 선택한 다음 Customer 엔터티 확인란을 선택합니다.

  10. 솔루션을 빌드합니다.

  11. 클라이언트 프로젝트의 Generated_Code 폴더에서 생성된 코드 SharedEntityExample.Web.g.cs 파일을 열고(기본적으로 숨겨져 있는 이 파일을 보려면 모두 표시해야 함) SalesDomainContextCustomerDomainContext가 있음을 확인합니다. 두 도메인 컨텍스트 개체를 사용하여 연결된 데이터를 로드하게 됩니다.

  12. 생성된 코드 파일을 닫습니다.

서버 프로젝트에서 코드를 사용하여 연결 정의

현재 각각 한 엔터티를 노출하는 두 엔터티 모델과 두 도메인 서비스가 있습니다. 적절한 도메인 서비스를 호출하여 각 엔터티에서 별도로 데이터를 로드할 수 있습니다. 그러나 두 엔터티의 데이터가 결합된 데이터를 로드하려면 이러한 엔터티 간의 관계를 정의해야 합니다. 다음 단계는 서버 프로젝트에서 관계를 정의하는 방법을 보여 줍니다.

서버 프로젝트에서 연결을 정의하려면

  1. 서버 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가새 항목을 선택합니다.

  2. 범주 목록에서 을 선택한 다음 클래스 템플릿을 선택합니다.

  3. 클래스 이름을 SalesOrderHeader.cs(또는 SalesOrderHeader.vb)로 지정한 다음 추가를 클릭합니다.

  4. SalesOrderHeader 클래스 파일에서 partial 키워드를 클래스 선언에 추가합니다.

    Partial Public Class SalesOrderHeader
    
    End Class
    
    namespace SharedEntityExample.Web
    {
        public partial class SalesOrderHeader
        {
        }
    }
    
  5. Customer 형식의 개체를 반환하는 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. System.ServiceModel.DomainServicesSystem.ComponentModel.DataAnnotations 네임스페이스에 대한 using(또는 Imports) 문을 추가합니다.

  7. ExternalReferenceAttribute 특성을 Customer 속성에 추가합니다.

  8. 다음 값을 사용하여 AssociationAttribute 특성을 Customer 속성에 추가합니다.

    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. 솔루션을 빌드합니다.

  10. 클라이언트 프로젝트의 Generated_Code 폴더에서 생성된 코드 파일을 열고 이제 SalesOrderHeader 클래스에 ExternalReferenceAttributeAssociationAttribute 특성이 포함된 Customer 속성이 있음을 확인합니다.

  11. 생성된 코드 파일을 닫습니다.

두 엔터티에서 데이터 로드

다른 도메인 컨텍스트의 엔터티를 참조하는 속성은 참조된 엔터티가 원래 도메인 컨텍스트에서 로드될 때까지 null입니다. 참조된 엔터티는 자동으로 로드되지 않습니다. 상호 참조된 엔터티에 액세스하기 전에 원래 도메인 컨텍스트를 통해 엔터티를 로드해야 합니다.

두 엔터티에서 데이터를 로드하려면

  1. 클라이언트 프로젝트에서 MainPage.xaml 파일을 엽니다.

  2. 도구 상자에서 Grid 요소 안으로 DataGrid 컨트롤을 끌어 옵니다.

    XML 네임스페이스와 Data 어셈블리에 대한 참조가 추가됩니다.

  3. 다음 XAML과 같이 DataGrid의 이름을 SalesGrid로 지정하고 결합된 데이터를 표시할 열을 정의합니다.

    <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. 코드 숨김 파일 MainPage.xaml.cs(또는 MainPage.xaml.vb)를 엽니다.

  5. SharedEntityExample.WebSystem.ServiceModel.DomainServices.Client 네임스페이스에 대한 using(또는 Imports) 문을 추가합니다.

  6. SalesDomainContextCustomerDomainContext의 인스턴스에 대한 변수를 만듭니다.

    Private salesContext As New SalesDomainContext()
    Private customerContext As New CustomerDomainContext()
    
    private SalesDomainContext salesContext = new SalesDomainContext();
    private CustomerDomainContext customerContext = new CustomerDomainContext();
    
  7. 생성자에서 AddReference 메서드를 호출하여 도메인 컨텍스트 개체 간의 참조를 추가하고 Load 메서드를 호출하여 각 엔터티를 로드한 다음 판매 엔터티를 DataGridItemsSource로 설정합니다.

    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. 솔루션을 실행합니다.

    두 엔터티 모델과 도메인 서비스에 있는 두 엔터티의 데이터를 표시하는 DataGrid 인스턴스가 표시됩니다.

클라이언트 프로젝트에서 코드를 사용하여 연결 정의

서버 프로젝트에 코드를 추가할 필요 없이 클라이언트에서 엔터티 간의 연결을 정의할 수도 있습니다. 이 방법은 데이터를 함께 표시하는 클라이언트 목표를 달성하기 위해서만 사용되는 서버 프로젝트에서 새 속성을 도입하지 않으려는 경우 효과적입니다.

클라이언트 프로젝트에서 코드를 사용하여 연결을 정의하려면

  1. 서버 프로젝트에서 이전에 추가한 전체 SalesOrderHeader.cs(또는 SalesOrderHeader.vb) 파일을 삭제하거나 주석으로 처리합니다.

  2. 생성된 코드 파일에 더 이상 SalesOrderHeader 개체에 대한 Customer 속성이 없도록 솔루션을 빌드합니다.

  3. 클라이언트 프로젝트에서 SalesOrderHeader.cs(또는 SalesOrderHeader.vb)라는 새 클래스 파일을 추가합니다.

  4. SalesOrderHeader 클래스 파일에서 partial 키워드를 클래스 선언에 추가하고 네임스페이스를 SharedEntityExample.Web으로 변경합니다. Visual Basic을 사용하는 경우 Namespace 문을 사용하여 Web 네임스페이스를 지정할 수 있습니다.

    이 클래스는 생성된 코드 파일에서 클래스를 확장합니다. 생성된 엔터티 클래스에는 서버 프로젝트의 네임스페이스가 있습니다.

  5. System.ServiceModel.DomainServices, System.ServiceModel.DomainServices.ClientSystem.ComponentModel.DataAnnotations 네임스페이스에 대한 using(Visual Basic의 경우 Imports) 문을 추가합니다.

  6. 연결을 설정하려면 다음 코드 샘플과 같이 Customer 속성이나 SalesOrderHeader 클래스를 정의하고 ExternalReferenceAttributeAssociationAttribute 특성으로 표시합니다.

    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. F5 키를 눌러 솔루션을 실행합니다.

    해당 도메인 서비스의 두 개별 엔터티 모델에 있는 각 엔터티에서 공유되는 데이터를 표시하는 DataGrid 인스턴스가 이제 브라우저에 표시됩니다.