방법: 사용자 지정 데이터 클래스 인터페이스 구현(Entity Framework)
EDM(엔터티 데이터 모델)에서 사용자 지정 데이터 클래스를 사용할 때는 클래스에서 다음과 같은 사용자 지정 데이터 클래스 인터페이스를 구현해야 합니다.
IEntityWithChangeTracker. 변경 내용 추적을 설정합니다.
IEntityWithKey. 선택적 요소입니다. 엔터티 키를 노출합니다.
IEntityWithRelationships. 연결이 있는 엔터티에 필요합니다.
자세한 내용은 사용자 지정 데이터 클래스 인터페이스 구현(Entity Framework)을 참조하십시오. 사용자 지정 클래스와 속성을 CSDL(개념 스키마 정의 언어) 파일에 정의된 엔터티로 매핑하는 EDM 특성만 적용해야 합니다. 자세한 내용은 방법: 사용자 지정 개체와 엔터티 매핑(Entity Framework)을 참조하십시오.
데이터 클래스 인터페이스를 직접 구현하는 대신 EntityObject에서 상속할 수도 있습니다. EDM에서 사용자 지정 데이터 클래스를 사용할 때는 이 방법을 사용하는 것이 좋습니다. 자세한 내용은 개체 사용자 지정(Entity Framework) 및 방법: EntityObject 및 ComplexObject 기본 클래스에서 상속(Entity Framework)을 참조하십시오.
사용자 지정 데이터 클래스 인터페이스를 구현하려면
다음 예제처럼 IEntityWithChangeTracker, IEntityWithKey 및 IEntityWithRelationships 인터페이스를 구현하도록 각 사용자 지정 데이터 클래스 정의를 수정합니다.
<EdmEntityTypeAttribute(NamespaceName:="Microsoft.Samples.Edm", Name:="Order")> _ Public Class Order Implements IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
[EdmEntityTypeAttribute(NamespaceName = "Microsoft.Samples.Edm", Name = "Order")] public class Order : IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
다음 예제처럼 각 사용자 지정 데이터 클래스에서 EntityKey 속성을 명시적으로 구현합니다(옵션).
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
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; } } }
다음 예제처럼 각 사용자 지정 데이터 클래스에서 SetChangeTracker 메서드를 명시적으로 구현합니다.
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
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); } }
이 메서드는 데이터 속성의 변경 내용을 개체 서비스에 보고하는 데 필요합니다.
IEntityWithRelationships의 경우 다음 예제처럼 RelationshipManager 속성을 명시적으로 구현합니다.
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
RelationshipManager _relationships = null; // Define a relationship manager for the class. RelationshipManager IEntityWithRelationships.RelationshipManager { get { if (null == _relationships) _relationships = RelationshipManager.Create(this); return _relationships; } }
각 데이터 클래스의 설정할 수 있는 스칼라 속성에서 속성 값을 설정하기 전에 EntityMemberChanging에 대한 호출을 추가하고 속성을 설정한 후 EntityMemberChanged에 대한 호출을 추가합니다. 이는 다음 예제에서 확인할 수 있습니다.
<EdmScalarPropertyAttribute(IsNullable:=False)> _ Public Property Status() As Byte Get Return _status End Get Set(ByVal value As Byte) If _status <> value Then ' Report the change if the change tracker exists. If Not _changeTracker Is Nothing Then _changeTracker.EntityMemberChanging("Status") _status = value _changeTracker.EntityMemberChanged("Status") Else _status = value End If End If End Set End Property
[EdmScalarPropertyAttribute(IsNullable = false)] public byte Status { get { return _status; } set { if (_status != value) { // Report the change if the change tracker exists. if (_changeTracker != null) { _changeTracker.EntityMemberChanging("Status"); _status = value; _changeTracker.EntityMemberChanged("Status"); } else { _status = value; } } } }
각 데이터 클래스의 설정할 수 있는 복합 속성에서 속성 값을 설정하기 전에 EntityComplexMemberChanging에 대한 호출을 추가하고 속성을 설정한 후 EntityComplexMemberChanged에 대한 호출을 추가합니다.
예제
이 예제에서는 사용자 지정 데이터 클래스 Order 및 LineItem과 복합 형식 OrderInfo를 보여 줍니다. 이 두 사용자 지정 클래스는 AdventureWorks 데이터베이스의 SalesOrderHeader 및 SalesOrderDetail 테이블에 매핑됩니다. 두 엔터티 클래스는 세 개의 사용자 지정 데이터 클래스 인터페이스를 모두 구현합니다. OrderInfo 복합 형식 클래스는 권장되는 변경 내용 추적 구현을 보여 줍니다.
Option Explicit On
Option Strict On
Imports System
Imports System.Data.SqlTypes
Imports System.Collections.Generic
Imports System.Text
Imports System.Data
Imports System.Data.Objects.DataClasses
Imports System.Data.Metadata.Edm
Imports Microsoft.Samples.Edm
<Assembly: EdmSchemaAttribute()>
<Assembly: EdmRelationshipAttribute("Microsoft.Samples.Edm", _
"FK_LineItem_Order_OrderId", "Order", _
RelationshipMultiplicity.One, GetType(Order), "LineItem", _
RelationshipMultiplicity.Many, GetType(LineItem))>
Namespace Microsoft.Samples.Edm
<EdmEntityTypeAttribute(NamespaceName:="Microsoft.Samples.Edm", Name:="Order")> _
Public Class Order
Implements IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
' Define private property variables.
Private _orderId As Integer
Private _orderDate As DateTime
Private _dueDate As DateTime
Private _shipDate As DateTime
Private _status As Byte
Private _customer As Integer
Private _subTotal As Decimal
Private _tax As Decimal
Private _freight As Decimal
Private _totalDue As Decimal
Private _extendedInfo As OrderInfo
#Region "ExplicitImplementation"
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
#End Region
' Public properties of the Order object.
<EdmScalarPropertyAttribute(EntityKeyProperty:=True, IsNullable:=False)> _
Public Property OrderId() As Integer
Get
Return _orderId
End Get
Set(ByVal value As Integer)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("OrderId")
_orderId = value
_changeTracker.EntityMemberChanged("OrderId")
Else
_orderId = value
End If
End Set
End Property
' Navigation property that returns a collection of line items.
<EdmRelationshipNavigationPropertyAttribute("Microsoft.Samples.Edm", "FK_LineItem_Order_OrderId", "LineItem")> _
Public ReadOnly Property LineItem() As EntityCollection(Of LineItem)
Get
Return CType(Me, IEntityWithRelationships).RelationshipManager.GetRelatedCollection(Of LineItem) _
("FK_LineItem_Order_OrderId", "LineItem")
End Get
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property OrderDate() As Date
Get
Return _orderDate
End Get
Set(ByVal value As DateTime)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("OrderDate")
_orderDate = value
_changeTracker.EntityMemberChanged("OrderDate")
Else
_orderDate = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property DueDate() As Date
Get
Return _dueDate
End Get
Set(ByVal value As Date)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("DueDate")
_changeTracker.EntityMemberChanged("DueDate")
Else
_dueDate = value
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property ShipDate() As Date
Get
Return _shipDate
End Get
Set(ByVal value As Date)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("ShipDate")
_changeTracker.EntityMemberChanged("ShipDate")
Else
_shipDate = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Status() As Byte
Get
Return _status
End Get
Set(ByVal value As Byte)
If _status <> value Then
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Status")
_status = value
_changeTracker.EntityMemberChanged("Status")
Else
_status = value
End If
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Customer() As Integer
Get
Return _customer
End Get
Set(ByVal value As Integer)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Customer")
_customer = value
_changeTracker.EntityMemberChanged("Customer")
Else
_customer = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property SubTotal() As Decimal
Get
Return _subTotal
End Get
Set(ByVal value As Decimal)
If _subTotal <> value Then
' Validate the value before setting it.
If value < 0 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString, "SubTotal"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("SubTotal")
_subTotal = value
_changeTracker.EntityMemberChanged("SubTotal")
Else
_subTotal = value
End If
' Recalculate the order total.
CalculateOrderTotal()
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property TaxAmt() As Decimal
Get
Return _tax
End Get
Set(ByVal value As Decimal)
' Validate the value before setting it.
If value < 0 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Tax"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("TaxAmt")
_tax = value
_changeTracker.EntityMemberChanged("TaxAmt")
Else
_tax = value
End If
' Recalculate the order total.
CalculateOrderTotal()
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Freight() As Decimal
Get
Return _freight
End Get
Set(ByVal value As Decimal)
If _freight <> value Then
' Validate the value before setting it.
If value < 0 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Freight"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Freight")
_freight = value
_changeTracker.EntityMemberChanging("Freight")
Else
_freight = value
End If
' Recalculate the order total.
CalculateOrderTotal()
End If
End Set
End Property
Public ReadOnly Property TotalDue() As Decimal
Get
Return _totalDue
End Get
End Property
<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
Private Sub CalculateOrderTotal()
' Update the total due as a sum of the other cost properties.
_totalDue = _subTotal + _tax + _freight
End Sub
End Class
' 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
<EdmComplexTypeAttribute(NamespaceName:="Microsoft.Samples.Edm", Name:="OrderInfo")> _
Partial Public Class OrderInfo
Inherits ComplexTypeChangeTracker
Private _orderNumber As String
Private _purchaseOrder As String
Private _accountNumber As String
Private _comment As String
Private _extendedInfo As OrderInfo
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
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property OrderNumber() As String
Get
Return _orderNumber
End Get
Set(ByVal value As String)
' Validate the value before setting it.
If value.Length > 25 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidString, _
"OrderNumber", "25"))
End If
' Report the change if the change tracker exists.
If Not _complexChangeTracker Is Nothing Then
ReportMemberChanging("OrderNumber")
_orderNumber = value
ReportMemberChanged("OrderNumber")
Else
_orderNumber = value
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property PurchaseOrder() As String
Get
Return _purchaseOrder
End Get
Set(ByVal value As String)
If (value <> Nothing) AndAlso value.Length > 25 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidString, _
"PurchaseOrder", "25"))
End If
If _purchaseOrder <> value Then
' Report the change if the change tracker exists.
If Not _complexChangeTracker Is Nothing Then
ReportMemberChanging("PurchaseOrder")
_purchaseOrder = value
ReportMemberChanged("PurchaseOrder")
Else
_purchaseOrder = value
End If
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property AccountNumber() As String
Get
Return _accountNumber
End Get
Set(ByVal value As String)
' Validate the value before setting it.
If (value <> Nothing) AndAlso value.Length > 15 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidString, _
"AccountNumber", "15"))
End If
' Report the change if the change tracker exists.
If Not _complexChangeTracker Is Nothing Then
ReportMemberChanging("AccountNumber")
_accountNumber = value
ReportMemberChanged("AccountNumber")
Else
_accountNumber = value
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property Comment() As String
Get
Return _comment
End Get
Set(ByVal value As String)
' Validate the value before setting it.
If (value <> Nothing) AndAlso value.Length > 128 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidString, _
"Comment", "128"))
End If
If _comment <> value Then
' Report the change if the change tracker exists.
If Not _complexChangeTracker Is Nothing Then
ReportMemberChanging("Comment")
_comment = value
ReportMemberChanged("Comment")
Else
_comment = value
End If
End If
End Set
End Property
End Class
<EdmEntityTypeAttribute(NamespaceName:="Microsoft.Samples.Edm", Name:="LineItem")> _
Public Class LineItem
Implements IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
' Define private property variables.
Dim _lineItemId As Integer
Dim _trackingNumber As String
Dim _quantity As Short
Dim _product As Integer
Dim _price As Decimal
Dim _discount As Decimal
Dim _total As Decimal
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
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.
' Changing an existing value will cause an exception.
If _entityKey Is Nothing Then
' 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 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
' Defines a navigation property to the Order class.
<EdmRelationshipNavigationPropertyAttribute("Microsoft.Samples.Edm", _
"FK_LineItem_Order_OrderId", "Order")> _
Public Property Order() As Order
Get
Return CType(Me, _
IEntityWithRelationships).RelationshipManager.GetRelatedReference(Of Order) _
("FK_LineItem_Order_OrderId", "Order").Value
End Get
Set(ByVal value As Order)
CType(Me, _
IEntityWithRelationships).RelationshipManager.GetRelatedReference(Of Order) _
("FK_LineItem_Order_OrderId", "Order").Value = value
End Set
End Property
<EdmScalarPropertyAttribute(EntityKeyProperty:=True, IsNullable:=False)> _
Public Property LineItemId() As Integer
Get
Return _lineItemId
End Get
Set(ByVal value As Integer)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("LineItemId")
_lineItemId = value
_changeTracker.EntityMemberChanged("LineItemId")
Else
_lineItemId = value
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property TrackingNumber() As String
Get
Return _trackingNumber
End Get
Set(ByVal value As String)
If _trackingNumber <> value Then
' Validate the value before setting it.
If value.Length > 25 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidString, _
"TrackingNumber", "25"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("TrackingNumber")
_trackingNumber = value
_changeTracker.EntityMemberChanged("TrackingNumber")
Else
_trackingNumber = value
End If
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Quantity() As Short
Get
Return _quantity
End Get
Set(ByVal value As Short)
If _quantity <> value Then
' Validate the value before setting it.
If value < 1 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Quantity"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Quantity")
_quantity = value
_changeTracker.EntityMemberChanged("Quantity")
Else
_quantity = value
End If
' Update the line total.
CalculateLineTotal()
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Product() As Integer
Get
Return _product
End Get
Set(ByVal value As Integer)
' Validate the value before setting it.
If value < 1 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Product"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Product")
_product = value
_changeTracker.EntityMemberChanged("Product")
Else
_product = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Price() As Decimal
Get
Return _price
End Get
Set(ByVal value As Decimal)
If _price <> value Then
' Validate the value before setting it.
If value < 0 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Price"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Price")
_price = value
_changeTracker.EntityMemberChanged("Price")
Else
_price = value
End If
' Update the line total.
CalculateLineTotal()
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Discount() As Decimal
Get
Return _discount
End Get
Set(ByVal value As Decimal)
' Validate the value before setting it.
If value < 0 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Discount"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Discount")
_discount = value
_changeTracker.EntityMemberChanged("Discount")
Else
_discount = value
End If
End Set
End Property
Public ReadOnly Property Total() As Decimal
Get
Return _total
End Get
End Property
Private Sub CalculateLineTotal()
_total = (_quantity * (_price - _discount))
End Sub
End Class
End Namespace
using System;
using System.Data.SqlTypes;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Objects.DataClasses;
using System.Data.Metadata.Edm;
using Microsoft.Samples.Edm;
//using Microsoft.Samples.Edm;
[assembly: EdmSchemaAttribute()]
[assembly: EdmRelationshipAttribute("Microsoft.Samples.Edm",
"FK_LineItem_Order_OrderId", "Order",
RelationshipMultiplicity.One, typeof(Order), "LineItem",
RelationshipMultiplicity.Many, typeof(LineItem))]
namespace Microsoft.Samples.Edm
{
[EdmEntityTypeAttribute(NamespaceName = "Microsoft.Samples.Edm", Name = "Order")]
public class Order : IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
{
// Define private property variables.
private int _orderId;
private DateTime _orderDate;
private DateTime _dueDate;
private DateTime _shipDate;
private byte _status;
private int _customer;
private decimal _subTotal;
private decimal _tax;
private decimal _freight;
private decimal _totalDue;
private OrderInfo _extendedInfo;
#region ExplicitImplementation
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;
}
}
#endregion
// Public properties of the Order object.
[EdmScalarPropertyAttribute(EntityKeyProperty = true, IsNullable = false)]
public int OrderId
{
get
{
return _orderId;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("OrderId");
_orderId = value;
_changeTracker.EntityMemberChanged("OrderId");
}
else
{
_orderId = value;
}
}
}
// Navigation property that returns a collection of line items.
[EdmRelationshipNavigationPropertyAttribute("Microsoft.Samples.Edm", "FK_LineItem_Order_OrderId", "LineItem")]
public System.Data.Objects.DataClasses.EntityCollection<LineItem> LineItem
{
get
{
return ((IEntityWithRelationships)(this)).RelationshipManager.
GetRelatedCollection<LineItem>("FK_LineItem_Order_OrderId", "LineItem");
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public DateTime OrderDate
{
get
{
return _orderDate;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("OrderDate");
_orderDate = value;
_changeTracker.EntityMemberChanged("OrderDate");
}
else
{
_orderDate = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public DateTime DueDate
{
get
{
return _dueDate;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("DueDate");
_dueDate = value;
_changeTracker.EntityMemberChanged("DueDate");
}
else
{
_dueDate = value;
}
}
}
[EdmScalarPropertyAttribute()]
public DateTime ShipDate
{
get
{
return _shipDate;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("ShipDate");
_shipDate = value;
_changeTracker.EntityMemberChanged("ShipDate");
}
else
{
_shipDate = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public byte Status
{
get
{
return _status;
}
set
{
if (_status != value)
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Status");
_status = value;
_changeTracker.EntityMemberChanged("Status");
}
else
{
_status = value;
}
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public int Customer
{
get
{
return _customer;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Customer");
_customer = value;
_changeTracker.EntityMemberChanged("Customer");
}
else
{
_customer = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public decimal SubTotal
{
get
{
return _subTotal;
}
set
{
if (_subTotal != value)
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "SubTotal" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("SubTotal");
_subTotal = value;
_changeTracker.EntityMemberChanged("SubTotal");
}
else
{
_subTotal = value;
}
// Recalculate the order total.
CalculateOrderTotal();
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public decimal TaxAmt
{
get
{
return _tax;
}
set
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Tax" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("TaxAmt");
_tax = value;
_changeTracker.EntityMemberChanged("TaxAmt");
}
else
{
_tax = value;
}
// Recalculate the order total.
CalculateOrderTotal();
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public decimal Freight
{
get
{
return _freight;
}
set
{
if (_freight != value)
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Freight" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Freight");
_freight = value;
_changeTracker.EntityMemberChanging("Freight");
}
else
{
_freight = value;
}
// Recalculate the order total.
CalculateOrderTotal();
}
}
}
public decimal TotalDue
{
get
{
return _totalDue;
}
}
[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);
}
}
}
private void CalculateOrderTotal()
{
// Update the total due as a sum of the other cost properties.
_totalDue = _subTotal + _tax + _freight;
}
}
// 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);
}
}
}
[EdmComplexTypeAttribute(NamespaceName = "Microsoft.Samples.Edm", Name = "OrderInfo")]
public partial class OrderInfo : ComplexTypeChangeTracker
{
private string _orderNumber;
private string _purchaseOrder;
private string _accountNumber;
private string _comment;
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);
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public string OrderNumber
{
get
{
return _orderNumber;
}
set
{
// Validate the value before setting it.
if (value.Length > 25)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidString,
new string[3] { value, "OrderNumber", "25" }));
}
// Report the change if the change tracker exists.
if (_complexChangeTracker != null)
{
ReportMemberChanging("OrderNumber");
_orderNumber = value;
ReportMemberChanged("OrderNumber");
}
else
{
_orderNumber = value;
}
}
}
[EdmScalarPropertyAttribute()]
public string PurchaseOrder
{
get
{
return _purchaseOrder;
}
set
{
// Validate the value before setting it.
if ((value != null) && value.Length > 25)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidString,
new string[3] { value, "PurchaseOrder", "25" }));
}
if (_purchaseOrder != value)
{
// Report the change if the change tracker exists.
if (_complexChangeTracker != null)
{
ReportMemberChanging("PurchaseOrder");
_purchaseOrder = value;
ReportMemberChanged("PurchaseOrder");
}
else
{
_purchaseOrder = value;
}
}
}
}
[EdmScalarPropertyAttribute()]
public string AccountNumber
{
get
{
return _accountNumber;
}
set
{
// Validate the value before setting it.
if ((value != null) && value.Length > 15)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidString,
new string[3] { value, "AccountNumber", "15" }));
}
if (_purchaseOrder != value)
{
// Report the change if the change tracker exists.
if (_complexChangeTracker != null)
{
ReportMemberChanging("AccountNumber");
_accountNumber = value;
ReportMemberChanged("AccountNumber");
}
else
{
_accountNumber = value;
}
}
}
}
[EdmScalarPropertyAttribute()]
public string Comment
{
get
{
return _comment;
}
set
{
// Validate the value before setting it.
if ((value != null) && value.Length > 128)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidString,
new string[3] { value, "Comment", "128" }));
}
if (_comment != value)
{
// Report the change if the change tracker exists.
if (_complexChangeTracker != null)
{
ReportMemberChanging("Comment");
_comment = value;
ReportMemberChanged("Comment");
}
else
{
_comment = value;
}
}
}
}
}
[EdmEntityTypeAttribute(NamespaceName = "Microsoft.Samples.Edm",
Name = "LineItem")]
public class LineItem : IEntityWithRelationships,
IEntityWithChangeTracker, IEntityWithKey
{
// Define private property variables.
int _lineItemId;
string _trackingNumber;
short _quantity;
int _product;
decimal _price;
decimal _discount;
decimal _total;
IEntityChangeTracker _changeTracker = null;
// Specify the IEntityChangeTracker to use for tracking changes.
void IEntityWithChangeTracker.SetChangeTracker(IEntityChangeTracker changeTracker)
{
_changeTracker = 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.
// Changing an existing value will cause an exception.
if (_entityKey == null)
{
// 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;
}
}
// Defines a navigation property to the Order class.
[EdmRelationshipNavigationPropertyAttribute("Microsoft.Samples.Edm", "FK_LineItem_Order_OrderId", "Order")]
public Order Order
{
get
{
return ((IEntityWithRelationships)(this)).RelationshipManager.
GetRelatedReference<Order>("FK_LineItem_Order_OrderId", "Order").Value;
}
set
{
((IEntityWithRelationships)(this)).RelationshipManager.
GetRelatedReference<Order>("FK_LineItem_Order_OrderId", "Order").Value = value;
}
}
[EdmScalarPropertyAttribute(EntityKeyProperty = true, IsNullable = false)]
public int LineItemId
{
get
{
return _lineItemId;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("LineItemId");
_lineItemId = value;
_changeTracker.EntityMemberChanged("LineItemId");
}
else
{
_lineItemId = value;
}
}
}
[EdmScalarPropertyAttribute()]
public string TrackingNumber
{
get
{
return _trackingNumber;
}
set
{
if (_trackingNumber != value)
{
// Validate the value before setting it.
if (value.Length > 25)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidString,
new string[3] {value,"TrackingNumber", "25"}));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("TrackingNumber");
_trackingNumber = value;
_changeTracker.EntityMemberChanged("TrackingNumber");
}
else
{
_trackingNumber = value;
}
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public short Quantity
{
get
{
return _quantity;
}
set
{
if (_quantity != value)
{
// Validate the value before setting it.
if (value < 1)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Quantity" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Quantity");
_quantity = value;
_changeTracker.EntityMemberChanged("Quantity");
}
else
{
_quantity = value;
}
// Update the line total.
CalculateLineTotal();
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public int Product
{
get
{
return _product;
}
set
{
// Validate the value before setting it.
if (value < 1)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Product" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Product");
_product = value;
_changeTracker.EntityMemberChanged("Product");
}
else
{
_product = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public decimal Price
{
get
{
return _price;
}
set
{
if (_price != value)
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Price" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Price");
_price = value;
_changeTracker.EntityMemberChanged("Price");
}
else
{
_price = value;
}
// Update the line total.
CalculateLineTotal();
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public decimal Discount
{
get
{
return _discount;
}
set
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Discount" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Discount");
_discount = value;
_changeTracker.EntityMemberChanged("Discount");
}
else
{
_discount = value;
}
}
}
public decimal Total
{
get
{
return _total;
}
}
private void CalculateLineTotal()
{
_total = (_quantity * (_price - _discount));
}
}
}
참고 항목
작업
방법: 사용자 지정 개체를 사용할 수 있도록 엔터티 데이터 모델 사용자 지정(Entity Framework)