IEntityWithRelationships Interface
Defines an entity type with a relationship to one or more other entity type.
Assembly: System.Data.Entity (in System.Data.Entity.dll)
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.