다음을 통해 공유


사용자 지정 데이터 클래스 인터페이스 구현(Entity Framework)

EDM(엔터티 데이터 모델)에서 사용자 지정 데이터 클래스를 사용하려면 EntityObjectComplexObject에서 상속하는 것이 좋습니다. EntityObjectComplexObject에서 상속할 수 없는 경우 또는 프레임워크로부터 더 강력한 독립성이 필요한 경우를 위해 Entity Framework에서는 사용자 지정 데이터 클래스 인터페이스 집합을 제공합니다. EntityObject에서 상속하지 않을 경우, EDM에서 사용자 지정 데이터 클래스를 사용하려면 이 인터페이스를 구현해야 합니다. 구현하는 인터페이스는 사용자 지정 데이터 클래스 및 응용 프로그램의 요구 사항에 따라 달라집니다.

  • IEntityWithKey
    선택 사항입니다. 성능 향상을 위해 엔터티 키를 개체 서비스에 노출합니다.

    IEntityWithKeyEntityKey 속성을 정의합니다. 개체 서비스에서는 EntityKey 속성을 사용하여 개체 컨텍스트의 개체를 관리합니다.

    IEntityWithKey를 구현하지 않기로 선택하면 관련 개체를 로드할 때, 개체 컨텍스트에 개체를 연결할 때 또는 키가 필요한 다른 작업을 수행할 때 성능이 감소하며 메모리 사용이 증가하는 것을 확인할 수 있습니다.

  • IEntityWithRelationships
    연결이 있는 엔터티에 필요합니다. 개체 서비스에서 개체 간의 관계를 관리할 수 있습니다.

    IEntityWithRelationshipsRelationshipManager 속성을 정의합니다. 개체 서비스는 다른 개체와의 관계 관리에 사용되는 RelationshipManager에 액세스할 때 RelationshipManager 속성을 사용합니다.

자세한 내용은 방법: 사용자 지정 데이터 클래스 인터페이스 구현(Entity Framework)을 참조하십시오.

EntityObject에서 상속하는 사용자 지정 데이터 클래스와 마찬가지로, 이 인터페이스를 구현하는 클래스는 다음 요구 사항을 충족해야 합니다.

  • CSDL(개념 스키마 정의 언어) 파일에 정의된 엔터티 형식별로 개체가 하나씩 있어야 합니다.

  • 네임스페이스, 클래스 및 데이터 속성에는 해당 EDM 특성이 적용되어야 합니다.

  • EDM 특성이 적용된 네임스페이스, 클래스 및 데이터 속성의 이름은 해당 CSDL 파일에 있는 이름과 일치해야 합니다.

자세한 내용은 개체 사용자 지정(Entity Framework)을 참조하십시오.

다음 예제에서는 Order 개체를 위해 이 인터페이스를 구현하는 데 필요한 코드를 보여 줍니다. 여기서 OrderSalesOrderHeader 테이블을 기반으로 합니다.

Dim _changeTracker As IEntityChangeTracker = Nothing

' Specify the IEntityChangeTracker to use for tracking changes.
Private Sub SetChangeTracker(ByVal changeTracker As IEntityChangeTracker) _
    Implements IEntityWithChangeTracker.SetChangeTracker
    _changeTracker = changeTracker

    ' Every time the change tracker is set, we must also set all the 
    ' complex type change trackers.
    If Not _extendedInfo Is Nothing Then
        _extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker)
    End If
End Sub

Dim _entityKey As EntityKey = Nothing

' Define the EntityKey property for the class.
Property EntityKey() As EntityKey Implements IEntityWithKey.EntityKey
    Get
        Return _entityKey
    End Get
    Set(ByVal value As EntityKey)
        ' Set the EntityKey property, if it is not set.
        ' Report the change if the change tracker exists.
        If Not _changeTracker Is Nothing Then
            _changeTracker.EntityMemberChanging(StructuralObject.EntityKeyPropertyName)
            _entityKey = value
            _changeTracker.EntityMemberChanged(StructuralObject.EntityKeyPropertyName)
        Else
            _entityKey = value
        End If
    End Set
End Property

Dim _relationships As RelationshipManager = Nothing

' Define a relationship manager for the class.
ReadOnly Property RelationshipManager() As RelationshipManager _
Implements IEntityWithRelationships.RelationshipManager
    Get
        If _relationships Is Nothing Then
            _relationships = RelationshipManager.Create(Me)
        End If
        Return _relationships
    End Get
End Property
IEntityChangeTracker _changeTracker = null;

// Specify the IEntityChangeTracker to use for tracking changes.
void IEntityWithChangeTracker.SetChangeTracker(IEntityChangeTracker changeTracker)
{
    _changeTracker = changeTracker;

    // Every time the change tracker is set, we must also set all the 
    // complex type change trackers.
    if (_extendedInfo != null)
    {
        _extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker);
    }
}

EntityKey _entityKey = null;

// Define the EntityKey property for the class.
EntityKey IEntityWithKey.EntityKey
{
    get 
    { 
        return _entityKey; 
    }
    set
    {
        // Set the EntityKey property, if it is not set.
        // Report the change if the change tracker exists.
        if (_changeTracker != null)
        {
            _changeTracker.EntityMemberChanging(StructuralObject.EntityKeyPropertyName);
            _entityKey = value;
            _changeTracker.EntityMemberChanged(StructuralObject.EntityKeyPropertyName);
        }
        else
        {
            _entityKey = value;
        }
    }
}

RelationshipManager _relationships = null;

// Define a relationship manager for the class.
RelationshipManager IEntityWithRelationships.RelationshipManager
{
    get
    {
        if (null == _relationships)
            _relationships = RelationshipManager.Create(this);
        return _relationships;
    }
}

복합 형식

복합 형식은 스칼라 속성이 엔터티 내에 구성되도록 하는 엔터티 형식의 비스칼라 속성입니다. 자세한 내용은 복합 형식(EDM)을 참조하십시오. 복합 형식 개체의 변경 내용을 추적하려면 사용자 지정 변경 추적 코드를 작성해야 합니다. 따라서, 가능한 한 EntityObjectComplexObject에서 상속하는 것이 좋습니다. 복합 형식 개체의 경우, 구현할 사용자 지정 데이터 클래스 인터페이스가 없습니다. 그러나 ComplexObject에서 상속하지 않는 복합 형식 개체에서 변경 추적을 구현할 때 다음 절차를 적용할 수 있습니다.

Note참고

개체에 대해 사용자 지정 데이터 클래스 인터페이스를 구현할 뿐 아니라 ComplexObject에서 상속하도록 선택하는 경우에도 다음 절차에서 설명하는 대로 사용자 지정 변경 추적을 구현해야 합니다.

복합 형식 개체에 대해 변경 추적을 구현하려면

  1. 엔터티 형식에 대해 사용자 지정 데이터 인터페이스를 구현합니다. 자세한 내용은 방법: 사용자 지정 데이터 클래스 인터페이스 구현(Entity Framework)을 참조하십시오.

  2. 복합 형식이 EDM의 개념 및 매핑 섹션에 제대로 정의되었는지 확인합니다. 자세한 내용은 복합 형식(EDM)을 참조하십시오.

  3. ComplexTypeChangeTracker라는 추상 기본 클래스를 정의합니다.

    ' Base class for complex types that implements change tracking.
    Public MustInherit Class ComplexTypeChangeTracker
        Protected _complexChangeTracker As IEntityChangeTracker = Nothing
        Private _rootComplexPropertyName As String
    
        ' Gets an IEntityChangeTracker to call for properties change. 
        ' You must do this in order to track changes.
        Public Overridable Sub SetComplexChangeTracker( _
            ByVal rootComplexPropertyName As String, _
            ByVal complexChangeTracker As IEntityChangeTracker)
            _rootComplexPropertyName = rootComplexPropertyName
            _complexChangeTracker = complexChangeTracker
        End Sub
    
        ' Protected method that is called before the change for change tracking 
        ' each of the scalar properties in the complex type.
        Protected Sub ReportMemberChanging(ByVal scalarPropertyName As String)
            If Not _complexChangeTracker Is Nothing Then
                _complexChangeTracker.EntityComplexMemberChanging( _
                    _rootComplexPropertyName, Me, scalarPropertyName)
            End If
        End Sub
    
        ' Protected method that is called after the change for change tracking 
        ' each of the scalar properties in the complex type.
        Protected Sub ReportMemberChanged(ByVal scalarPropertyName As String)
            If Not _complexChangeTracker Is Nothing Then
                _complexChangeTracker.EntityComplexMemberChanged( _
                    _rootComplexPropertyName, Me, scalarPropertyName)
            End If
        End Sub
    End Class
    
    // Base class for complex types that implements change tracking.
    public abstract class ComplexTypeChangeTracker
    {
        protected IEntityChangeTracker _complexChangeTracker = null;
        private string _rootComplexPropertyName;
    
        // Gets an IEntityChangeTracker to call for properties change. 
        // You must do this in order to track changes.
        virtual public void SetComplexChangeTracker(string rootComplexPropertyName, IEntityChangeTracker complexChangeTracker)
        {
            _rootComplexPropertyName = rootComplexPropertyName;
            _complexChangeTracker = complexChangeTracker;
        }
    
        // Protected method that is called before the change for change tracking 
        // each of the scalar properties in the complex type.
        protected void ReportMemberChanging(string scalarPropertyName)
        {
            if (null != _complexChangeTracker)
            {
                _complexChangeTracker.EntityComplexMemberChanging(_rootComplexPropertyName,
                                                           this, scalarPropertyName);
            }
        }
    
        // Protected method that is called after the change for change tracking 
        // each of the scalar properties in the complex type.
        protected void ReportMemberChanged(string scalarPropertyName)
        {
            if (null != _complexChangeTracker)
            {
                _complexChangeTracker.EntityComplexMemberChanged(_rootComplexPropertyName,
                                                          this, scalarPropertyName);
            }
        }
    }
    
  4. ComplexTypeChangeTracker에서 상속하는 복합 형식 클래스를 정의하고 EdmComplexTypeAttribute를 적용합니다.

    <EdmComplexTypeAttribute(NamespaceName:="Microsoft.Samples.Edm", Name:="OrderInfo")> _
    Partial Public Class OrderInfo
        Inherits ComplexTypeChangeTracker
    
    [EdmComplexTypeAttribute(NamespaceName = "Microsoft.Samples.Edm", Name = "OrderInfo")]
    public partial class OrderInfo : ComplexTypeChangeTracker
    {
    
  5. 복합 형식 클래스에서 SetComplexChangeTracker 메서드를 재정의합니다.

    Public Overrides Sub SetComplexChangeTracker(ByVal rootComplexPropertyName As String, _
        ByVal changeTracker As IEntityChangeTracker)
    
        ' Call SetChangeTracker on the base class to set the change tracker 
        ' and the name of the root complex type property on the entity.
        MyBase.SetComplexChangeTracker(rootComplexPropertyName, changeTracker)
    End Sub
    
    override public void SetComplexChangeTracker(string rootComplexPropertyName, IEntityChangeTracker changeTracker)
    {
        // Call SetChangeTracker on the base class to set the change tracker 
        // and the name of the root complex type property on the entity.
        base.SetComplexChangeTracker(rootComplexPropertyName, changeTracker);
    }
    
  6. 복합 형식의 스칼라 속성에서 표준 변경 추적을 구현합니다. 자세한 내용은 사용자 지정 데이터 클래스의 변경 내용 보고(Entity Framework)를 참조하십시오.

  7. 엔터티 형식의 복합 속성에 EdmComplexPropertyAttribute를 적용하고, 복합 속성 변경 시 변경 추적 장치를 재설정하도록 SetComplexChangeTracker 호출을 추가합니다.

    <EdmComplexPropertyAttribute()> _
            Public Property ExtendedInfo() As OrderInfo
        Get
            Return _extendedInfo
        End Get
        Set(ByVal value As OrderInfo)
    
            ' For a complex type any changes in the complex type 
            ' properties all get tracked together.
            ' The change tracker may be Nothing during object materialization.
            If Not _changeTracker Is Nothing Then
    
                ' Since this is a complex property, we need to reset the change 
                ' tracker on the complex type. 
                If Not _extendedInfo Is Nothing Then
                    ' Reset the change tracker.
                    _extendedInfo.SetComplexChangeTracker("ExtendedInfo", Nothing)
                End If
    
                ' Report the change.
                _changeTracker.EntityMemberChanging("ExtendedInfo")
                _extendedInfo = value
                _changeTracker.EntityMemberChanging("ExtendedInfo")
    
            Else
                _extendedInfo = value
            End If
    
            ' Rest the change tracker. Complex type property cannot be Nothing.
            If Not _extendedInfo Is Nothing Then
                _extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker)
            End If
        End Set
    End Property
    
    [EdmComplexPropertyAttribute()]
    public OrderInfo ExtendedInfo
    {
        get
        {
            return _extendedInfo;
        }
        set
        {
            // For a complex type any changes in the complex type 
            // properties all get tracked together.
            // The change tracker may be null during object materialization.
            if (_changeTracker != null)
            {
                // Since this is a complex property, we need to reset the change 
                // tracker on the complex type. 
                if (_extendedInfo != null)
                {
                    // Reset the change tracker.
                    _extendedInfo.SetComplexChangeTracker("ExtendedInfo", null);
                }
    
                // Report the change.
                _changeTracker.EntityMemberChanging("ExtendedInfo");
                _extendedInfo = value;
                _changeTracker.EntityMemberChanged("ExtendedInfo");
            }
            else
            {
                _extendedInfo = value;
            }
    
            // Reset the change tracker. Complex type property cannot be null.
            if (_extendedInfo != null)
            {
                _extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker);
            }
        }
    }
    
  8. 각 복합 속성별로 4 ~ 7단계를 반복합니다.

  9. 엔터티 형식에 대한 System.Data.Objects.DataClasses.IEntityWithChangeTracker.SetChangeTracker(System.Data.Objects.DataClasses.IEntityChangeTracker) 구현에서 SetComplexChangeTracker 호출을 삽입하여 변경 추적 장치를 설정합니다. 형식의 복합 속성별로 이 작업을 한 번씩 수행합니다.

    ' Every time the change tracker is set, we must also set all the 
    ' complex type change trackers.
    If Not _extendedInfo Is Nothing Then
        _extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker)
    End If
    
    // Every time the change tracker is set, we must also set all the 
    // complex type change trackers.
    if (_extendedInfo != null)
    {
        _extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker);
    }
    

참고 항목

참조

EDM 생성기(EdmGen.exe)

개념

개체 서비스 개요(Entity Framework)