다음을 통해 공유


데이터

이 단원에서는 WCF RIA Services에서 데이터 모델링, 데이터 유효성 검사 및 데이터 동시성 확인과 관련된 시나리오를 다루는 방법에 대해 설명합니다. RIA(리치 인터넷 응용 프로그램)의 클라이언트에서 데이터를 업데이트하거나 삭제하거나 만드는 인터페이스를 제공할 때는 몇 가지 복잡한 데이터 관계를 모델링해야 하고 데이터 변경 내용을 커밋하기 전에 사용자의 데이터가 유효하며 데이터 원본의 데이터와 비교해서 최신 상태인지 확인해야 하는 경우가 많습니다.

일반적으로 엔터티 데이터 모델 또는 LINQ to SQL을 사용하여 관계형 데이터베이스에 있는 데이터를 모델링합니다. 하지만 RIA Services 프로젝트에서 데이터베이스를 사용할 필요는 없습니다. 모든 형식의 개체를 사용하여 데이터를 저장할 수 있습니다. 클라이언트 프로젝트에서 데이터 작업을 쉽게 할 수 있도록 하는 코드는 중간 계층에서 사용된 데이터 액세스 기술이나 스키마를 실제로 알지 못한다는 점에서 데이터 원본을 알 수 없습니다.

데이터 관계

RIA Services 는 계층적 모델, 다형성 상속 모델, 여러 엔터티의 값을 통합하는 프레젠테이션 모델, 두 개 이상의 도메인 서비스의 값을 포함하는 모델과 같은 복잡한 데이터 관계와 상호 작용할 수 있는 기능을 제공합니다. 계층적 모델은 OrderOrderDetails와 같은 부모와 자식 복합 관계 또는 Employee 모델의 다른 엔터티를 가리키는 ManagerID에 대한 필드를 포함하는 Employee 모델과 같은 재귀적 관계를 나타냅니다. 자세한 내용은 구성 계층 구조를 참조하십시오.

상속 모델에서는 Customer 엔터티와 이 엔터티에서 파생되는 PublicSectorCustomerPrivateSectorCustomer라는 두 엔터티를 포함하는 데이터 구조를 나타낼 수 있습니다. 도메인 작업을 사용하여 형식을 쿼리하고 업데이트할 수 있습니다. 자세한 내용은 데이터 모델의 상속을 참조하십시오.

RIA Services V1.0 SP1에서는 비 엔터티 복합 형식에 대한 지원이 추가되었습니다. 특히 코드 생성, 메타데이터, 심층적 유효성 검사, 변경 추적, 편집 세션 및 복합 형식 매개 변수에 대한 지원이 제공됩니다. 따라서 Address와 같은 사용자 지정 형식을 이제 엔터티 속성 또는 DomainService 메서드의 매개 변수나 반환 값으로 사용할 수 있습니다. 자세한 내용은 복합 형식 항목을 참조하십시오.

RIA Services V1.0 SP1에서는 여러 도메인 서비스와 엔터티 공유에 대한 지원이 추가되었습니다. 따라서 DomainService 클래스를 보다 논리적으로 분할하는 데 필요한 유연성이 제공됩니다. 자세한 내용은 공유 엔터티 항목을 참조하십시오.

프레젠테이션 모델에서는 데이터 원본 테이블의 구조에 직접 연결되지 않는 프레젠테이션 계층에 대한 형식을 빌드할 수 있습니다. 예를 들어 Customer, CustomerAddress 및 Address 테이블의 데이터 클래스를 기반으로 하는 CustomerPresentation이라는 데이터 형식을 빌드할 수 있습니다. 프레젠테이션 형식에서 프레젠테이션 계층에 관련된 값만 집계합니다. 데이터 리포지토리를 변경한 경우 프레젠테이션 형식만 변경할 수 있으며 해당 데이터와 상호 작용하는 코드 클라이언트 응용 프로그램은 업데이트할 수 없습니다. RIA Services 에서는 프레젠테이션 형식을 통해 데이터를 업데이트할 수 있습니다. 자세한 내용은 프레젠테이션 모델을 참조하십시오.

마지막으로, 응용 프로그램에서 다양한 데이터 원본의 데이터를 표시하거나 단일 엔터티를 두 개 이상의 도메인 서비스에 노출해야 할 수 있습니다. RIA Services 에서는 이를 위해 다양한 DomainContext 형식의 엔터티 간 참조를 지원합니다. 예를 들어 전자 상거래 웹 사이트에서 주문 처리 시스템의 데이터를 타사 도메인 서비스의 제품과 통합해야 할 수 있습니다. 자세한 내용은 연습: 여러 도메인 서비스 간 엔터티 공유를 참조하십시오.

데이터 주석 및 유효성 검사

RIA Services 응용 프로그램에서 데이터 클래스를 사용할 때 유효성 검사 규칙을 지정하고 데이터 표시 방법을 지정하며 엔터티 클래스 간의 관계를 설정하는 클래스나 멤버에 특성을 적용할 수 있습니다. System.ComponentModel.DataAnnotations 네임스페이스에는 데이터 특성으로 사용되는 클래스가 포함됩니다. 데이터 클래스나 멤버에서 이러한 특성을 적용하여 데이터 정의를 중앙 집중화하며 여러 위치에서 동일한 규칙을 다시 적용할 필요가 없습니다. 데이터 주석 특성은 유효성 검사 특성, 표시 특성 및 데이터 모델링 특성이라는 세 범주로 구성됩니다. 자세한 내용은 Using Data Annotations to Customize Data Classes방법: 데이터 유효성 검사를 참조하십시오. 유효성 검사에는 다음 특성을 사용할 수 있습니다.

  1. DataTypeAttribute

  2. RangeAttribute

  3. RegularExpressionAttribute

  4. RequiredAttribute

  5. StringLengthAttribute

  6. CustomValidationAttribute

엔터티 데이터 모델 또는 LINQ to SQL 클래스와 같이 자동으로 생성되는 데이터 클래스로 작업할 경우 다음에 클래스를 다시 생성할 때 특성이 손실되기 때문에 생성된 클래스에 특성을 직접 적용하지 않습니다. 대신 데이터 클래스의 메타데이터 클래스를 만들고 메타데이터 클래스에 특성을 적용합니다. 메타데이터 클래스는 데이터 클래스에서 메타데이터 형식으로 지정되는 partial 클래스입니다. 자세한 내용은 방법: 메타데이터 클래스 추가를 참조하십시오.

다음 예제에서는 RoundtripOriginalAttribute, RequiredAttribute, StringLengthAttributeExcludeAttribute 특성이 일부 속성에 적용된 메타데이터 클래스를 보여 줍니다.

<MetadataTypeAttribute(GetType(Address.AddressMetadata))>  _
Partial Public Class Address
    
    Friend NotInheritable Class AddressMetadata
        
        'Metadata classes are not meant to be instantiated.
        Private Sub New()
            MyBase.New
        End Sub
        
        Public AddressID As Integer

        <Required()> _
        <StringLength(60)> _
        <RoundtripOriginal()> _
        Public AddressLine1 As String

        <RoundtripOriginal()> _
        Public AddressLine2 As String

        <Required()> _
        <StringLength(30)> _
        <RoundtripOriginal()> _
        Public City As String

        <RoundtripOriginal()> _
        Public CountryRegion As String
        
        Public CustomerAddresses As EntityCollection(Of CustomerAddress)

        <RoundtripOriginal()> _
        Public ModifiedDate As DateTime

        <Required()> _
        <RoundtripOriginal()> _
        Public PostalCode As String

        <Exclude()> _
        Public rowguid As Guid

        <RoundtripOriginal()> _
        Public StateProvince As String
    End Class
End Class
[MetadataTypeAttribute(typeof(Address.AddressMetadata))]
public partial class Address
{

    internal sealed class AddressMetadata
    {
        // Metadata classes are not meant to be instantiated.
        private AddressMetadata()
        {
        }

        public int AddressID { get; set; }

        [Required]
        [StringLength(60)]
        [RoundtripOriginal]
        public string AddressLine1 { get; set; }

        [RoundtripOriginal]
        public string AddressLine2 { get; set; }

        [Required]
        [StringLength(30)]
        [RoundtripOriginal]
        public string City { get; set; }

        [RoundtripOriginal]
        public string CountryRegion { get; set; }

        public EntityCollection<CustomerAddress> CustomerAddresses { get; set; }

        [RoundtripOriginal]
        public DateTime ModifiedDate { get; set; }

        [Required]
        [RoundtripOriginal]
        public string PostalCode { get; set; }

        [Exclude]
        public Guid rowguid { get; set; }

        [RoundtripOriginal]
        public string StateProvince { get; set; }
    }
}

공유 코드 파일을 추가하고 해당 파일에서 유효성 검사 논리를 구현하는 클래스를 만들어 사용자 지정 유효성 검사 특성을 만들 수 있습니다. 사용자 지정 유효성 검사 클래스를 정의할 때 클라이언트 프로젝트에서 클래스가 올바르게 생성되려면 최소한 자동 구현된 속성 이외의 다른 몇 가지 코드를 제공해야 합니다. 예제는 방법: 데이터 유효성 검사를 참조하십시오.

Entity 클래스는 INotifyDataErrorInfo 인터페이스를 구현합니다. 이 인터페이스는 동기 및 비동기 유효성 검사를 지원하는 멤버를 정의합니다. INotifyDataErrorInfo 인터페이스가 있으면 유효성 검사 오류가 예외를 발생시키지 않고 클라이언트 프로젝트에 전달됩니다. INotifyDataErrorInfo에 대한 자세한 내용은 INotifyDataErrorInfo Interface를 참조하십시오.

ValidationResult 클래스의 인스턴스를 만들어 유효성 검사 결과를 반환합니다.

다음 예제에서는 ValidationResult 클래스의 인스턴스를 통해 결과를 반환하는 사용자 지정 유효성 검사 클래스를 보여 줍니다.

Imports System
Imports System.ComponentModel.DataAnnotations

Public Module GenderValidator
    Public Function IsGenderValid(ByVal gender As String, ByVal context As ValidationContext) As ValidationResult
        If gender = "M" OrElse gender = "m" OrElse gender = "F" OrElse gender = "f" Then
            Return ValidationResult.Success
        Else
            Return New ValidationResult("The Gender field only has two valid values 'M'/'F'", New String() {"Gender"})
        End If
    End Function
End Module
using System;
using System.ComponentModel.DataAnnotations;

namespace HRApp.Web
{
    public static class GenderValidator
    {
        public static ValidationResult IsGenderValid(string gender, ValidationContext context)
        {
            if (gender == "M" || gender == "m" || gender == "F" || gender == "f")
            {
                return ValidationResult.Success;
            }
            else
            {
                return new ValidationResult("The Gender field only has two valid values 'M'/'F'", new string[] { "Gender" });
            }
        }
    }
}

데이터 동시성

WCF RIA Services에는 데이터 일관성을 보장하기 위해 낙관적 동시성이 지원되며, 개발자는 데이터 원본을 업데이트할 때 발생할 수 있는 잠재적인 충돌을 해결하기 위한 논리를 제공해야 합니다. 사용자가 데이터를 업데이트하거나 삭제할 수 있도록 하는 경우 데이터 원본의 데이터가 다른 프로세스에 의해 변경되지 않았는지 확인합니다.

기본적으로 RIA Services 는 데이터 동시성을 확인하기 위해 전체 원본 엔터티를 변경된 값과 함께 데이터 액세스 레이어에 전달하지 않습니다. 대신 RIA Services 는 RoundtripOriginalAttribute 특성으로 표시된 멤버만 저장하고 다시 전달합니다. 이 구현에서는 동시성 확인에 포함할 멤버만 지정하여 응용 프로그램의 성능을 최적화할 수 있습니다.

이러한 동작은 Entity Framewor를 사용할 경우 메타데이터 클래스의 속성, 메타데이터 클래스 자체 또는 여러 메타데이터 클래스 자체에 특성을 적용하여 구현됩니다. 또한 POCO 정의 데이터 모델을 사용할 경우 CLR 형식의 속성 또는 클래스에 직접 적용할 수도 있습니다. 자세한 내용은 방법: 메타데이터 클래스 추가를 참조하십시오.

트랜잭션

RIA Services 프레임워크에서는 트랜잭션이 자동으로 생성되지 않지만 변경 내용을 전송할 때 명시적 트랜잭션을 추가할 수 있습니다. 명시적 트랜잭션을 직접 만들려면 Submit 메서드를 재정의합니다. 자세한 내용은 방법: 도메인 서비스에 명시적 트랜잭션 추가를 참조하십시오.

참고 항목

개념

WCF RIA Services 보안