This documentation is archived and is not being maintained.

IEntityWithRelationships Interface

Defines an entity type with a relationship to one or more other entity type.

Namespace:  System.Data.Objects.DataClasses
Assembly:  System.Data.Entity (in System.Data.Entity.dll)

'Declaration
Public Interface IEntityWithRelationships
'Usage
Dim instance As IEntityWithRelationships

IEntityWithRelationships defines the features that must be implemented by an entity type that has relationships to other types. Relationships are defined as associations in the Entity Data Model.

EntityObject is the base class for all entity types generated by the Entity Data Model tools. The EntityObject class implements IEntityWithRelationships.

To use custom data classes together with an Entity Data Model (EDM), you must either inherit from EntityObject or implement a set of interfaces. When you implement custom data class interfaces, you must implement IEntityWithRelationships when the entity type is related to other types. For information about how to customize your objects, see Implementing an Entity Data Model with Custom Objects (Entity Framework).

The example in this topic is based on the Adventure Works Sales Model. The example implements the IEntityWithRelationships interface in the Order type.

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

Windows 7, Windows Vista, Windows XP SP2, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5 SP1
Show: