How to: Implement Custom Data Class Interfaces (Entity Framework)
When you use custom data classes with an Entity Data Model (EDM), the classes must implement the following custom data class interfaces:
IEntityWithChangeTracker. Enables change tracking.
IEntityWithKey. Optional. Exposes an entity key.
IEntityWithRelationships. Required for entities with associations.
For more information, see Implementing Custom Data Class Interfaces (Entity Framework). You must also apply EDM attributes that map the custom classes and properties to entities defined in the conceptual schema definition language (CSDL) file. For more information, see How to: Map Custom Objects to Entities (Entity Framework).
Instead of directly implementing data class interfaces, you can also inherit from EntityObject. This is the recommended way to use custom data classes with an EDM. For more information, see Customizing Objects (Entity Framework) and How to: Inherit from the EntityObject and ComplexObject Base Classes (Entity Framework).
To implement custom data class interfaces
Modify the definition of each custom data class so that it implements the IEntityWithChangeTracker, IEntityWithKey, and IEntityWithRelationships interfaces, as in the following example:
<EdmEntityTypeAttribute(NamespaceName:="Microsoft.Samples.Entity", Name:="Order")> _ Public Class Order Implements IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
[EdmEntityTypeAttribute(NamespaceName = "Microsoft.Samples.Entity", Name = "Order")] public class Order : IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
(Optional) Explicitly implement the EntityKey property in each custom data class, as in the following example:
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. ' 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. // Report the change if the change tracker exists. if (_changeTracker != null) { _changeTracker.EntityMemberChanging(StructuralObject.EntityKeyPropertyName); _entityKey = value; _changeTracker.EntityMemberChanged(StructuralObject.EntityKeyPropertyName); } else { _entityKey = value; } } }
Explicitly implement the SetChangeTracker method in each custom data class, as in the following example:
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); } }
This method is required to report changes in data properties to Object Services.
For IEntityWithRelationships, explicitly implement the RelationshipManager property, as in the following example:
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; } }
In the settable scalar properties of each data class, add a call to EntityMemberChanging before setting the property value, and add a call to EntityMemberChanged after the property is set. This is shown in the following example:
<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; } } } }
In the settable complex properties of each data class, add a call to EntityComplexMemberChanging before setting the property value, and add a call to EntityComplexMemberChanged after the property is set.
Example
This example shows the custom data classes Order and LineItem and a complex type OrderInfo. These custom classes are mapped to the SalesOrderHeader and SalesOrderDetail tables in the AdventureWorks database. Both entity classes implement all three custom data class interfaces. The OrderInfo complex type class demonstrates a suggested change tracking implementation.
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
<Assembly: EdmSchemaAttribute()>
<Assembly: EdmRelationshipAttribute("Microsoft.Samples.Entity", _
"LineItem_Order_OrderId", "Order", _
RelationshipMultiplicity.One, GetType(Order), "LineItems", _
RelationshipMultiplicity.Many, GetType(LineItem))>
<EdmEntityTypeAttribute(NamespaceName:="Microsoft.Samples.Entity", Name:="Order")> _
Public Class Order
Implements IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
' Define private property variables.
Private _orderId As Integer
Private _revision As Byte
Private _orderDate As DateTime
Private _dueDate As DateTime
Private _shipDate As DateTime
Private _onlineOrder As Boolean
Private _status As Byte
Private _customer As Integer
Private _contact As Integer
Private _billToAddress As Integer
Private _shipToAddress As Integer
Private _shipMethod As Integer
Private _subTotal As Decimal
Private _tax As Decimal
Private _freight As Decimal
Private _totalDue As Decimal
Private _extendedInfo As OrderInfo
Private _rowGuid As Guid
Private _modifiedDate As DateTime
#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.
' 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.Entity", "LineItem_Order_OrderId", "LineItems")> _
Public ReadOnly Property LineItems() As EntityCollection(Of LineItem)
Get
Return CType(Me, IEntityWithRelationships).RelationshipManager.GetRelatedCollection(Of LineItem) _
("LineItem_Order_OrderId", "LineItems")
End Get
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Revision() As Byte
Get
Return _revision
End Get
Set(ByVal value As Byte)
If _revision <> value Then
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Revision")
_revision = value
_changeTracker.EntityMemberChanged("Revision")
Else
_revision = value
End If
End If
End Set
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")
_dueDate = value
_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")
_shipDate = value
_changeTracker.EntityMemberChanged("ShipDate")
Else
_shipDate = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property OnlineOrder() As Boolean
Get
Return _onlineOrder
End Get
Set(ByVal value As Boolean)
If Not _onlineOrder = value Then
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("OnlineOrder")
_onlineOrder = value
_changeTracker.EntityMemberChanged("OnlineOrder")
Else
_onlineOrder = value
End If
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 Contact() As Integer
Get
Return _contact
End Get
Set(ByVal value As Integer)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Contact")
_contact = value
_changeTracker.EntityMemberChanged("Contact")
Else
_contact = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property BillToAddress() As Integer
Get
Return _billToAddress
End Get
Set(ByVal value As Integer)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("BillToAddress")
_billToAddress = value
_changeTracker.EntityMemberChanged("BillToAddress")
Else
_billToAddress = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property ShipToAddress() As Integer
Get
Return _shipToAddress
End Get
Set(ByVal value As Integer)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("ShipToAddress")
_shipToAddress = value
_changeTracker.EntityMemberChanged("ShipToAddress")
Else
_shipToAddress = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property ShipMethod() As Integer
Get
Return _shipMethod
End Get
Set(ByVal value As Integer)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("ShipMethod")
_shipMethod = value
_changeTracker.EntityMemberChanged("ShipMethod")
Else
_shipMethod = 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( _
Errors.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 Tax() 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( _
Errors.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( _
Errors.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
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property RowGuid() As Guid
Get
Return _rowGuid
End Get
Set(ByVal value As Guid)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("RowGuid")
_rowGuid = value
_changeTracker.EntityMemberChanged("RowGuid")
Else
_rowGuid = value
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property ModifiedDate() As Date
Get
Return _modifiedDate
End Get
Set(ByVal value As Date)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("ModifiedDate")
_modifiedDate = value
_changeTracker.EntityMemberChanged("ModifiedDate")
Else
_modifiedDate = value
End If
End Set
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.Entity", 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( _
Errors.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( _
Errors.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( _
Errors.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( _
Errors.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.Entity", Name:="LineItem")> _
Public Class LineItem
Implements IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
' Define private property variables.
Private _orderId As Integer
Private _lineItemId As Integer
Private _trackingNumber As String
Private _quantity As Short
Private _special As Integer
Private _product As Integer
Private _price As Decimal
Private _discount As Decimal
Private _total As Decimal
Private _rowGuid As Guid
Private _modifiedDate As DateTime
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.
' 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
' Defines a navigation property to the Order class.
<EdmRelationshipNavigationPropertyAttribute("Microsoft.Samples.Entity", _
"LineItem_Order_OrderId", "Order")> _
Public Property Order() As Order
Get
Return CType(Me, _
IEntityWithRelationships).RelationshipManager.GetRelatedReference(Of Order) _
("LineItem_Order_OrderId", "Order").Value
End Get
Set(ByVal value As Order)
CType(Me, _
IEntityWithRelationships).RelationshipManager.GetRelatedReference(Of Order) _
("LineItem_Order_OrderId", "Order").Value = value
End Set
End Property
<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
<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( _
Errors.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( _
Errors.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 Special() As Integer
Get
Return _special
End Get
Set(ByVal value As Integer)
If _special <> value Then
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Special")
_special = value
_changeTracker.EntityMemberChanged("Special")
Else
_special = value
End If
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( _
Errors.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( _
Errors.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( _
Errors.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
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property RowGuid() As Guid
Get
Return _rowGuid
End Get
Set(ByVal value As Guid)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("RowGuid")
_rowGuid = value
_changeTracker.EntityMemberChanged("RowGuid")
Else
_rowGuid = value
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property ModifiedDate() As Date
Get
Return _modifiedDate
End Get
Set(ByVal value As Date)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("ModifiedDate")
_modifiedDate = value
_changeTracker.EntityMemberChanged("ModifiedDate")
Else
_modifiedDate = 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
Public Class Errors
Public Const propertyNotValidNegative As String = _
"The value '{0}' for the {1} property is not valid. It cannot be a negative number or zero."
Public Const propertyNotValidString As String = _
"The value '{0}' for the {1} property is not valid."
End Class
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.Entity;
[assembly: EdmSchemaAttribute()]
[assembly: EdmRelationshipAttribute("Microsoft.Samples.Entity",
"LineItem_Order_OrderId", "Order",
RelationshipMultiplicity.One, typeof(Order), "LineItems",
RelationshipMultiplicity.Many, typeof(LineItem))]
namespace Microsoft.Samples.Entity
{
[EdmEntityTypeAttribute(NamespaceName = "Microsoft.Samples.Entity", Name = "Order")]
public class Order : IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
{
// Define private property variables.
private int _orderId;
private byte _revision;
private DateTime _orderDate;
private DateTime _dueDate;
private DateTime _shipDate;
private bool _onlineOrder;
private byte _status;
private int _customer;
private int _contact;
private int _billToAddress;
private int _shipToAddress;
private int _shipMethod;
private decimal _subTotal;
private decimal _tax;
private decimal _freight;
private decimal _totalDue;
private Guid _rowGuid;
private DateTime _modifiedDate;
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.
// 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.Entity", "LineItem_Order_OrderId", "LineItems")]
public EntityCollection<LineItem> LineItems
{
get
{
return ((IEntityWithRelationships)(this)).RelationshipManager.
GetRelatedCollection<LineItem>("Microsoft.Samples.Entity.LineItem_Order_OrderId", "LineItems");
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public byte Revision
{
get
{
return _revision;
}
set
{
if (_revision != value)
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Revision");
_revision = value;
_changeTracker.EntityMemberChanged("Revision");
}
else
{
_revision = value;
}
}
}
}
[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 bool OnlineOrder
{
get
{
return _onlineOrder;
}
set
{
if (_onlineOrder != value)
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("OnlineOrder");
_onlineOrder = value;
_changeTracker.EntityMemberChanged("OnlineOrder");
}
else
{
_onlineOrder = 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 int Contact
{
get
{
return _contact;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Contact");
_contact = value;
_changeTracker.EntityMemberChanged("Contact");
}
else
{
_contact = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public int BillToAddress
{
get
{
return _billToAddress;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("BillToAddress");
_billToAddress = value;
_changeTracker.EntityMemberChanged("BillToAddress");
}
else
{
_billToAddress = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public int ShipToAddress
{
get
{
return _shipToAddress;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("ShipToAddress");
_shipToAddress = value;
_changeTracker.EntityMemberChanged("ShipToAddress");
}
else
{
_shipToAddress = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public int ShipMethod
{
get
{
return _shipMethod;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("ShipMethod");
_shipMethod = value;
_changeTracker.EntityMemberChanged("ShipMethod");
}
else
{
_shipMethod = 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(
Errors.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 Tax
{
get
{
return _tax;
}
set
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Errors.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(
Errors.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();
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public Guid RowGuid
{
get
{
return _rowGuid;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("RowGuid");
_rowGuid = value;
_changeTracker.EntityMemberChanged("RowGuid");
}
else
{
_rowGuid = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public DateTime ModifiedDate
{
get
{
return _modifiedDate;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("ModifiedDate");
_modifiedDate = value;
_changeTracker.EntityMemberChanged("ModifiedDate");
}
else
{
_modifiedDate = value;
}
}
}
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.Entity", 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(
Errors.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(
Errors.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(
Errors.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(
Errors.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.Entity",
Name = "LineItem")]
public class LineItem : IEntityWithRelationships,
IEntityWithChangeTracker, IEntityWithKey
{
// Define private property variables.
private int _orderId;
private int _lineItemId;
private string _trackingNumber;
private short _quantity;
private int _special;
private int _product;
private decimal _price;
private decimal _discount;
private decimal _total;
private Guid _rowGuid;
private DateTime _modifiedDate;
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.
// 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.Entity", "LineItem_Order_OrderId", "Order")]
public Order Order
{
get
{
return ((IEntityWithRelationships)(this)).RelationshipManager.
GetRelatedReference<Order>("LineItem_Order_OrderId", "Order").Value;
}
set
{
((IEntityWithRelationships)(this)).RelationshipManager.
GetRelatedReference<Order>("LineItem_Order_OrderId", "Order").Value = value;
}
}
[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;
}
}
}
[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(
Errors.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(
Errors.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 Special
{
get
{
return _special;
}
set
{
if (_special != value)
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Special");
_special = value;
_changeTracker.EntityMemberChanged("Special");
}
else
{
_special = value;
}
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public int Product
{
get
{
return _product;
}
set
{
// Validate the value before setting it.
if (value < 1)
{
throw new ApplicationException(string.Format(
Errors.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(
Errors.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(
Errors.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;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public Guid RowGuid
{
get
{
return _rowGuid;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("RowGuid");
_rowGuid = value;
_changeTracker.EntityMemberChanged("RowGuid");
}
else
{
_rowGuid = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public DateTime ModifiedDate
{
get
{
return _modifiedDate;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("ModifiedDate");
_modifiedDate = value;
_changeTracker.EntityMemberChanged("ModifiedDate");
}
else
{
_modifiedDate = value;
}
}
}
public decimal Total
{
get
{
return _total;
}
}
private void CalculateLineTotal()
{
_total = (_quantity * (_price - _discount));
}
}
public class Errors
{
public const string propertyNotValidNegative =
@"The value '{0}' for the {1} property is not valid. It cannot be a negative number or zero.";
public const string propertyNotValidString =
@"The value '{0}' for the {1} property is not valid.";
}
}
See Also
Tasks
How to: Customize an Entity Data Model to Work with Custom Objects (Entity Framework)