Gewusst wie: Implementieren von Schnittstellen für benutzerdefinierte Datenklassen (Entity Framework)
Wenn Sie benutzerdefinierte Datenklassen mit einem Entitätsdatenmodell (EDM) verwenden, müssen die Klassen die folgenden Schnittstellen für benutzerdefinierte Datenklassen implementieren:
Ermöglicht das Nachverfolgen von Änderungen.
Optional. Macht einen Entitätsschlüssel verfügbar.
IEntityWithRelationships. Für Entitäten mit Zuordnungen erforderlich.
Weitere Informationen finden Sie unter Implementieren von Schnittstellen für benutzerdefinierte Datenklassen (Entity Framework). Außerdem müssen EDM-Attribute angelegt werden, die die benutzerdefinierten Klassen und Eigenschaften in der CSDL-Datei definierten Entitäten zuordnen. Weitere Informationen finden Sie unter Gewusst wie: Zuordnen von benutzerdefinierten Objekten zu Entitäten (Entity Framework).
Statt die Schnittstellen für die Datenklassen direkt zu implementieren, können sie auch vom EntityObject geerbt werden. Dies ist die empfohlene Methode für die Verwendung von benutzerdefinierten Datenklassen mit einem EDM. Weitere Informationen finden Sie unter Anpassen von Objekten (Entity Framework) und Gewusst wie: Erben von den Basisklassen 'EntityObject' und 'ComplexObject' (Entity Framework).
So implementieren Sie Schnittstellen für benutzerdefinierte Datenklassen
Ändern Sie die Definition jeder benutzerdefinierten Datenklasse, sodass die Schnittstellen IEntityWithChangeTracker, IEntityWithKey und IEntityWithRelationships implementiert werden, wie im folgenden Beispiel:
<EdmEntityTypeAttribute(NamespaceName:="Microsoft.Samples.Edm", Name:="Order")> _ Public Class Order Implements IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
[EdmEntityTypeAttribute(NamespaceName = "Microsoft.Samples.Edm", Name = "Order")] public class Order : IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
(Optional) Implementieren Sie die EntityKey-Eigenschaft explizit in jeder benutzerdefinierten Datenklasse, wie im folgenden Beispiel:
Dim _entityKey As EntityKey = Nothing ' Define the EntityKey property for the class. Property EntityKey() As EntityKey Implements IEntityWithKey.EntityKey Get Return _entityKey End Get Set(ByVal value As EntityKey) ' Set the EntityKey property, if it is not set. ' Report the change if the change tracker exists. If Not _changeTracker Is Nothing Then _changeTracker.EntityMemberChanging(StructuralObject.EntityKeyPropertyName) _entityKey = value _changeTracker.EntityMemberChanged(StructuralObject.EntityKeyPropertyName) Else _entityKey = value End If End Set End Property
EntityKey _entityKey = null; // Define the EntityKey property for the class. EntityKey IEntityWithKey.EntityKey { get { return _entityKey; } set { // Set the EntityKey property, if it is not set. // Report the change if the change tracker exists. if (_changeTracker != null) { _changeTracker.EntityMemberChanging(StructuralObject.EntityKeyPropertyName); _entityKey = value; _changeTracker.EntityMemberChanged(StructuralObject.EntityKeyPropertyName); } else { _entityKey = value; } } }
Implementieren Sie die SetChangeTracker-Methode explizit in jeder benutzerdefinierten Datenklasse, wie im folgenden Beispiel:
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); } }
Diese Methode ist erforderlich, um Änderungen von Dateneigenschaften an Object Services zu melden.
Implementieren Sie für IEntityWithRelationships die RelationshipManager-Eigenschaft explizit, wie im folgenden Beispiel:
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; } }
Fügen Sie in den festlegbaren skalaren Eigenschaften jeder Datenklasse vor dem Festlegen des Eigenschaftswerts einen Aufruf an EntityMemberChanging hinzu, und fügen Sie nach dem Festlegen der Eigenschaft einen Aufruf an EntityMemberChanged hinzu. Dies ist im folgenden Beispiel dargestellt:
<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; } } } }
Fügen Sie in den festlegbaren komplexen Eigenschaften jeder Datenklasse vor dem Festlegen des Eigenschaftswerts einen Aufruf an EntityComplexMemberChanging hinzu, und fügen Sie nach dem Festlegen der Eigenschaft einen Aufruf an EntityComplexMemberChanged hinzu.
Beispiel
In diesem Beispiel sind die benutzerdefinierten Datenklassen Order und LineItem sowie der komplexe Typ OrderInfo dargestellt. Diese benutzerdefinierten Klassen werden der SalesOrderHeader-Tabelle und der SalesOrderDetail-Tabelle in der AdventureWorks- Datenbank zugeordnet. Beide Entitätsklassen implementieren alle drei Schnittstellen für benutzerdefinierte Datenklassen. Die komplexe Typklasse OrderInfo veranschaulichet eine vorgeschlagene Implementierung der Änderungsnachverfolgung.
Option Explicit On
Option Strict On
Imports System
Imports System.Data.SqlTypes
Imports System.Collections.Generic
Imports System.Text
Imports System.Data
Imports System.Data.Objects.DataClasses
Imports System.Data.Metadata.Edm
Imports Microsoft.Samples.Edm
<Assembly: EdmSchemaAttribute()>
<Assembly: EdmRelationshipAttribute("Microsoft.Samples.Edm", _
"FK_LineItem_Order_OrderId", "Order", _
RelationshipMultiplicity.One, GetType(Order), "LineItem", _
RelationshipMultiplicity.Many, GetType(LineItem))>
Namespace Microsoft.Samples.Edm
<EdmEntityTypeAttribute(NamespaceName:="Microsoft.Samples.Edm", Name:="Order")> _
Public Class Order
Implements IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
' Define private property variables.
Private _orderId As Integer
Private _orderDate As DateTime
Private _dueDate As DateTime
Private _shipDate As DateTime
Private _status As Byte
Private _customer As Integer
Private _subTotal As Decimal
Private _tax As Decimal
Private _freight As Decimal
Private _totalDue As Decimal
Private _extendedInfo As OrderInfo
#Region "ExplicitImplementation"
Dim _changeTracker As IEntityChangeTracker = Nothing
' Specify the IEntityChangeTracker to use for tracking changes.
Private Sub SetChangeTracker(ByVal changeTracker As IEntityChangeTracker) _
Implements IEntityWithChangeTracker.SetChangeTracker
_changeTracker = changeTracker
' Every time the change tracker is set, we must also set all the
' complex type change trackers.
If Not _extendedInfo Is Nothing Then
_extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker)
End If
End Sub
Dim _entityKey As EntityKey = Nothing
' Define the EntityKey property for the class.
Property EntityKey() As EntityKey Implements IEntityWithKey.EntityKey
Get
Return _entityKey
End Get
Set(ByVal value As EntityKey)
' Set the EntityKey property, if it is not set.
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging(StructuralObject.EntityKeyPropertyName)
_entityKey = value
_changeTracker.EntityMemberChanged(StructuralObject.EntityKeyPropertyName)
Else
_entityKey = value
End If
End Set
End Property
Dim _relationships As RelationshipManager = Nothing
' Define a relationship manager for the class.
ReadOnly Property RelationshipManager() As RelationshipManager _
Implements IEntityWithRelationships.RelationshipManager
Get
If _relationships Is Nothing Then
_relationships = RelationshipManager.Create(Me)
End If
Return _relationships
End Get
End Property
#End Region
' Public properties of the Order object.
<EdmScalarPropertyAttribute(EntityKeyProperty:=True, IsNullable:=False)> _
Public Property OrderId() As Integer
Get
Return _orderId
End Get
Set(ByVal value As Integer)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("OrderId")
_orderId = value
_changeTracker.EntityMemberChanged("OrderId")
Else
_orderId = value
End If
End Set
End Property
' Navigation property that returns a collection of line items.
<EdmRelationshipNavigationPropertyAttribute("Microsoft.Samples.Edm", "FK_LineItem_Order_OrderId", "LineItem")> _
Public ReadOnly Property LineItem() As EntityCollection(Of LineItem)
Get
Return CType(Me, IEntityWithRelationships).RelationshipManager.GetRelatedCollection(Of LineItem) _
("FK_LineItem_Order_OrderId", "LineItem")
End Get
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property OrderDate() As Date
Get
Return _orderDate
End Get
Set(ByVal value As DateTime)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("OrderDate")
_orderDate = value
_changeTracker.EntityMemberChanged("OrderDate")
Else
_orderDate = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property DueDate() As Date
Get
Return _dueDate
End Get
Set(ByVal value As Date)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("DueDate")
_changeTracker.EntityMemberChanged("DueDate")
Else
_dueDate = value
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property ShipDate() As Date
Get
Return _shipDate
End Get
Set(ByVal value As Date)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("ShipDate")
_changeTracker.EntityMemberChanged("ShipDate")
Else
_shipDate = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Status() As Byte
Get
Return _status
End Get
Set(ByVal value As Byte)
If _status <> value Then
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Status")
_status = value
_changeTracker.EntityMemberChanged("Status")
Else
_status = value
End If
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Customer() As Integer
Get
Return _customer
End Get
Set(ByVal value As Integer)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Customer")
_customer = value
_changeTracker.EntityMemberChanged("Customer")
Else
_customer = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property SubTotal() As Decimal
Get
Return _subTotal
End Get
Set(ByVal value As Decimal)
If _subTotal <> value Then
' Validate the value before setting it.
If value < 0 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString, "SubTotal"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("SubTotal")
_subTotal = value
_changeTracker.EntityMemberChanged("SubTotal")
Else
_subTotal = value
End If
' Recalculate the order total.
CalculateOrderTotal()
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property TaxAmt() As Decimal
Get
Return _tax
End Get
Set(ByVal value As Decimal)
' Validate the value before setting it.
If value < 0 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Tax"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("TaxAmt")
_tax = value
_changeTracker.EntityMemberChanged("TaxAmt")
Else
_tax = value
End If
' Recalculate the order total.
CalculateOrderTotal()
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Freight() As Decimal
Get
Return _freight
End Get
Set(ByVal value As Decimal)
If _freight <> value Then
' Validate the value before setting it.
If value < 0 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Freight"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Freight")
_freight = value
_changeTracker.EntityMemberChanging("Freight")
Else
_freight = value
End If
' Recalculate the order total.
CalculateOrderTotal()
End If
End Set
End Property
Public ReadOnly Property TotalDue() As Decimal
Get
Return _totalDue
End Get
End Property
<EdmComplexPropertyAttribute()> _
Public Property ExtendedInfo() As OrderInfo
Get
Return _extendedInfo
End Get
Set(ByVal value As OrderInfo)
' For a complex type any changes in the complex type
' properties all get tracked together.
' The change tracker may be Nothing during object materialization.
If Not _changeTracker Is Nothing Then
' Since this is a complex property, we need to reset the change
' tracker on the complex type.
If Not _extendedInfo Is Nothing Then
' Reset the change tracker.
_extendedInfo.SetComplexChangeTracker("ExtendedInfo", Nothing)
End If
' Report the change.
_changeTracker.EntityMemberChanging("ExtendedInfo")
_extendedInfo = value
_changeTracker.EntityMemberChanging("ExtendedInfo")
Else
_extendedInfo = value
End If
' Rest the change tracker. Complex type property cannot be Nothing.
If Not _extendedInfo Is Nothing Then
_extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker)
End If
End Set
End Property
Private Sub CalculateOrderTotal()
' Update the total due as a sum of the other cost properties.
_totalDue = _subTotal + _tax + _freight
End Sub
End Class
' Base class for complex types that implements change tracking.
Public MustInherit Class ComplexTypeChangeTracker
Protected _complexChangeTracker As IEntityChangeTracker = Nothing
Private _rootComplexPropertyName As String
' Gets an IEntityChangeTracker to call for properties change.
' You must do this in order to track changes.
Public Overridable Sub SetComplexChangeTracker( _
ByVal rootComplexPropertyName As String, _
ByVal complexChangeTracker As IEntityChangeTracker)
_rootComplexPropertyName = rootComplexPropertyName
_complexChangeTracker = complexChangeTracker
End Sub
' Protected method that is called before the change for change tracking
' each of the scalar properties in the complex type.
Protected Sub ReportMemberChanging(ByVal scalarPropertyName As String)
If Not _complexChangeTracker Is Nothing Then
_complexChangeTracker.EntityComplexMemberChanging( _
_rootComplexPropertyName, Me, scalarPropertyName)
End If
End Sub
' Protected method that is called after the change for change tracking
' each of the scalar properties in the complex type.
Protected Sub ReportMemberChanged(ByVal scalarPropertyName As String)
If Not _complexChangeTracker Is Nothing Then
_complexChangeTracker.EntityComplexMemberChanged( _
_rootComplexPropertyName, Me, scalarPropertyName)
End If
End Sub
End Class
<EdmComplexTypeAttribute(NamespaceName:="Microsoft.Samples.Edm", Name:="OrderInfo")> _
Partial Public Class OrderInfo
Inherits ComplexTypeChangeTracker
Private _orderNumber As String
Private _purchaseOrder As String
Private _accountNumber As String
Private _comment As String
Private _extendedInfo As OrderInfo
Public Overrides Sub SetComplexChangeTracker(ByVal rootComplexPropertyName As String, _
ByVal changeTracker As IEntityChangeTracker)
' Call SetChangeTracker on the base class to set the change tracker
' and the name of the root complex type property on the entity.
MyBase.SetComplexChangeTracker(rootComplexPropertyName, changeTracker)
End Sub
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property OrderNumber() As String
Get
Return _orderNumber
End Get
Set(ByVal value As String)
' Validate the value before setting it.
If value.Length > 25 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidString, _
"OrderNumber", "25"))
End If
' Report the change if the change tracker exists.
If Not _complexChangeTracker Is Nothing Then
ReportMemberChanging("OrderNumber")
_orderNumber = value
ReportMemberChanged("OrderNumber")
Else
_orderNumber = value
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property PurchaseOrder() As String
Get
Return _purchaseOrder
End Get
Set(ByVal value As String)
If (value <> Nothing) AndAlso value.Length > 25 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidString, _
"PurchaseOrder", "25"))
End If
If _purchaseOrder <> value Then
' Report the change if the change tracker exists.
If Not _complexChangeTracker Is Nothing Then
ReportMemberChanging("PurchaseOrder")
_purchaseOrder = value
ReportMemberChanged("PurchaseOrder")
Else
_purchaseOrder = value
End If
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property AccountNumber() As String
Get
Return _accountNumber
End Get
Set(ByVal value As String)
' Validate the value before setting it.
If (value <> Nothing) AndAlso value.Length > 15 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidString, _
"AccountNumber", "15"))
End If
' Report the change if the change tracker exists.
If Not _complexChangeTracker Is Nothing Then
ReportMemberChanging("AccountNumber")
_accountNumber = value
ReportMemberChanged("AccountNumber")
Else
_accountNumber = value
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property Comment() As String
Get
Return _comment
End Get
Set(ByVal value As String)
' Validate the value before setting it.
If (value <> Nothing) AndAlso value.Length > 128 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidString, _
"Comment", "128"))
End If
If _comment <> value Then
' Report the change if the change tracker exists.
If Not _complexChangeTracker Is Nothing Then
ReportMemberChanging("Comment")
_comment = value
ReportMemberChanged("Comment")
Else
_comment = value
End If
End If
End Set
End Property
End Class
<EdmEntityTypeAttribute(NamespaceName:="Microsoft.Samples.Edm", Name:="LineItem")> _
Public Class LineItem
Implements IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
' Define private property variables.
Dim _lineItemId As Integer
Dim _trackingNumber As String
Dim _quantity As Short
Dim _product As Integer
Dim _price As Decimal
Dim _discount As Decimal
Dim _total As Decimal
Dim _changeTracker As IEntityChangeTracker = Nothing
' Specify the IEntityChangeTracker to use for tracking changes.
Private Sub SetChangeTracker(ByVal changeTracker As IEntityChangeTracker) _
Implements IEntityWithChangeTracker.SetChangeTracker
_changeTracker = changeTracker
End Sub
Dim _entityKey As EntityKey = Nothing
' Define the EntityKey property for the class.
Property EntityKey() As EntityKey Implements IEntityWithKey.EntityKey
Get
Return _entityKey
End Get
Set(ByVal value As EntityKey)
' Set the EntityKey property, if it is not set.
' Changing an existing value will cause an exception.
If _entityKey Is Nothing Then
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging(StructuralObject.EntityKeyPropertyName)
_entityKey = value
_changeTracker.EntityMemberChanged(StructuralObject.EntityKeyPropertyName)
Else
_entityKey = value
End If
End If
End Set
End Property
Dim _relationships As RelationshipManager = Nothing
' Define a relationship manager for the class.
ReadOnly Property RelationshipManager() As RelationshipManager _
Implements IEntityWithRelationships.RelationshipManager
Get
If _relationships Is Nothing Then
_relationships = RelationshipManager.Create(Me)
End If
Return _relationships
End Get
End Property
' Defines a navigation property to the Order class.
<EdmRelationshipNavigationPropertyAttribute("Microsoft.Samples.Edm", _
"FK_LineItem_Order_OrderId", "Order")> _
Public Property Order() As Order
Get
Return CType(Me, _
IEntityWithRelationships).RelationshipManager.GetRelatedReference(Of Order) _
("FK_LineItem_Order_OrderId", "Order").Value
End Get
Set(ByVal value As Order)
CType(Me, _
IEntityWithRelationships).RelationshipManager.GetRelatedReference(Of Order) _
("FK_LineItem_Order_OrderId", "Order").Value = value
End Set
End Property
<EdmScalarPropertyAttribute(EntityKeyProperty:=True, IsNullable:=False)> _
Public Property LineItemId() As Integer
Get
Return _lineItemId
End Get
Set(ByVal value As Integer)
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("LineItemId")
_lineItemId = value
_changeTracker.EntityMemberChanged("LineItemId")
Else
_lineItemId = value
End If
End Set
End Property
<EdmScalarPropertyAttribute()> _
Public Property TrackingNumber() As String
Get
Return _trackingNumber
End Get
Set(ByVal value As String)
If _trackingNumber <> value Then
' Validate the value before setting it.
If value.Length > 25 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidString, _
"TrackingNumber", "25"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("TrackingNumber")
_trackingNumber = value
_changeTracker.EntityMemberChanged("TrackingNumber")
Else
_trackingNumber = value
End If
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Quantity() As Short
Get
Return _quantity
End Get
Set(ByVal value As Short)
If _quantity <> value Then
' Validate the value before setting it.
If value < 1 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Quantity"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Quantity")
_quantity = value
_changeTracker.EntityMemberChanged("Quantity")
Else
_quantity = value
End If
' Update the line total.
CalculateLineTotal()
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Product() As Integer
Get
Return _product
End Get
Set(ByVal value As Integer)
' Validate the value before setting it.
If value < 1 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Product"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Product")
_product = value
_changeTracker.EntityMemberChanged("Product")
Else
_product = value
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Price() As Decimal
Get
Return _price
End Get
Set(ByVal value As Decimal)
If _price <> value Then
' Validate the value before setting it.
If value < 0 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Price"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Price")
_price = value
_changeTracker.EntityMemberChanged("Price")
Else
_price = value
End If
' Update the line total.
CalculateLineTotal()
End If
End Set
End Property
<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Discount() As Decimal
Get
Return _discount
End Get
Set(ByVal value As Decimal)
' Validate the value before setting it.
If value < 0 Then
Throw New ApplicationException(String.Format( _
My.Resources.propertyNotValidNegative, _
value.ToString(), "Discount"))
End If
' Report the change if the change tracker exists.
If Not _changeTracker Is Nothing Then
_changeTracker.EntityMemberChanging("Discount")
_discount = value
_changeTracker.EntityMemberChanged("Discount")
Else
_discount = value
End If
End Set
End Property
Public ReadOnly Property Total() As Decimal
Get
Return _total
End Get
End Property
Private Sub CalculateLineTotal()
_total = (_quantity * (_price - _discount))
End Sub
End Class
End Namespace
using System;
using System.Data.SqlTypes;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Objects.DataClasses;
using System.Data.Metadata.Edm;
using Microsoft.Samples.Edm;
//using Microsoft.Samples.Edm;
[assembly: EdmSchemaAttribute()]
[assembly: EdmRelationshipAttribute("Microsoft.Samples.Edm",
"FK_LineItem_Order_OrderId", "Order",
RelationshipMultiplicity.One, typeof(Order), "LineItem",
RelationshipMultiplicity.Many, typeof(LineItem))]
namespace Microsoft.Samples.Edm
{
[EdmEntityTypeAttribute(NamespaceName = "Microsoft.Samples.Edm", Name = "Order")]
public class Order : IEntityWithRelationships, IEntityWithChangeTracker, IEntityWithKey
{
// Define private property variables.
private int _orderId;
private DateTime _orderDate;
private DateTime _dueDate;
private DateTime _shipDate;
private byte _status;
private int _customer;
private decimal _subTotal;
private decimal _tax;
private decimal _freight;
private decimal _totalDue;
private OrderInfo _extendedInfo;
#region ExplicitImplementation
IEntityChangeTracker _changeTracker = null;
// Specify the IEntityChangeTracker to use for tracking changes.
void IEntityWithChangeTracker.SetChangeTracker(IEntityChangeTracker changeTracker)
{
_changeTracker = changeTracker;
// Every time the change tracker is set, we must also set all the
// complex type change trackers.
if (_extendedInfo != null)
{
_extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker);
}
}
EntityKey _entityKey = null;
// Define the EntityKey property for the class.
EntityKey IEntityWithKey.EntityKey
{
get
{
return _entityKey;
}
set
{
// Set the EntityKey property, if it is not set.
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging(StructuralObject.EntityKeyPropertyName);
_entityKey = value;
_changeTracker.EntityMemberChanged(StructuralObject.EntityKeyPropertyName);
}
else
{
_entityKey = value;
}
}
}
RelationshipManager _relationships = null;
// Define a relationship manager for the class.
RelationshipManager IEntityWithRelationships.RelationshipManager
{
get
{
if (null == _relationships)
_relationships = RelationshipManager.Create(this);
return _relationships;
}
}
#endregion
// Public properties of the Order object.
[EdmScalarPropertyAttribute(EntityKeyProperty = true, IsNullable = false)]
public int OrderId
{
get
{
return _orderId;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("OrderId");
_orderId = value;
_changeTracker.EntityMemberChanged("OrderId");
}
else
{
_orderId = value;
}
}
}
// Navigation property that returns a collection of line items.
[EdmRelationshipNavigationPropertyAttribute("Microsoft.Samples.Edm", "FK_LineItem_Order_OrderId", "LineItem")]
public System.Data.Objects.DataClasses.EntityCollection<LineItem> LineItem
{
get
{
return ((IEntityWithRelationships)(this)).RelationshipManager.
GetRelatedCollection<LineItem>("FK_LineItem_Order_OrderId", "LineItem");
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public DateTime OrderDate
{
get
{
return _orderDate;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("OrderDate");
_orderDate = value;
_changeTracker.EntityMemberChanged("OrderDate");
}
else
{
_orderDate = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public DateTime DueDate
{
get
{
return _dueDate;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("DueDate");
_dueDate = value;
_changeTracker.EntityMemberChanged("DueDate");
}
else
{
_dueDate = value;
}
}
}
[EdmScalarPropertyAttribute()]
public DateTime ShipDate
{
get
{
return _shipDate;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("ShipDate");
_shipDate = value;
_changeTracker.EntityMemberChanged("ShipDate");
}
else
{
_shipDate = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public byte Status
{
get
{
return _status;
}
set
{
if (_status != value)
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Status");
_status = value;
_changeTracker.EntityMemberChanged("Status");
}
else
{
_status = value;
}
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public int Customer
{
get
{
return _customer;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Customer");
_customer = value;
_changeTracker.EntityMemberChanged("Customer");
}
else
{
_customer = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public decimal SubTotal
{
get
{
return _subTotal;
}
set
{
if (_subTotal != value)
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "SubTotal" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("SubTotal");
_subTotal = value;
_changeTracker.EntityMemberChanged("SubTotal");
}
else
{
_subTotal = value;
}
// Recalculate the order total.
CalculateOrderTotal();
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public decimal TaxAmt
{
get
{
return _tax;
}
set
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Tax" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("TaxAmt");
_tax = value;
_changeTracker.EntityMemberChanged("TaxAmt");
}
else
{
_tax = value;
}
// Recalculate the order total.
CalculateOrderTotal();
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public decimal Freight
{
get
{
return _freight;
}
set
{
if (_freight != value)
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Freight" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Freight");
_freight = value;
_changeTracker.EntityMemberChanging("Freight");
}
else
{
_freight = value;
}
// Recalculate the order total.
CalculateOrderTotal();
}
}
}
public decimal TotalDue
{
get
{
return _totalDue;
}
}
[EdmComplexPropertyAttribute()]
public OrderInfo ExtendedInfo
{
get
{
return _extendedInfo;
}
set
{
// For a complex type any changes in the complex type
// properties all get tracked together.
// The change tracker may be null during object materialization.
if (_changeTracker != null)
{
// Since this is a complex property, we need to reset the change
// tracker on the complex type.
if (_extendedInfo != null)
{
// Reset the change tracker.
_extendedInfo.SetComplexChangeTracker("ExtendedInfo", null);
}
// Report the change.
_changeTracker.EntityMemberChanging("ExtendedInfo");
_extendedInfo = value;
_changeTracker.EntityMemberChanged("ExtendedInfo");
}
else
{
_extendedInfo = value;
}
// Reset the change tracker. Complex type property cannot be null.
if (_extendedInfo != null)
{
_extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker);
}
}
}
private void CalculateOrderTotal()
{
// Update the total due as a sum of the other cost properties.
_totalDue = _subTotal + _tax + _freight;
}
}
// Base class for complex types that implements change tracking.
public abstract class ComplexTypeChangeTracker
{
protected IEntityChangeTracker _complexChangeTracker = null;
private string _rootComplexPropertyName;
// Gets an IEntityChangeTracker to call for properties change.
// You must do this in order to track changes.
virtual public void SetComplexChangeTracker(string rootComplexPropertyName, IEntityChangeTracker complexChangeTracker)
{
_rootComplexPropertyName = rootComplexPropertyName;
_complexChangeTracker = complexChangeTracker;
}
// Protected method that is called before the change for change tracking
// each of the scalar properties in the complex type.
protected void ReportMemberChanging(string scalarPropertyName)
{
if (null != _complexChangeTracker)
{
_complexChangeTracker.EntityComplexMemberChanging(_rootComplexPropertyName,
this, scalarPropertyName);
}
}
// Protected method that is called after the change for change tracking
// each of the scalar properties in the complex type.
protected void ReportMemberChanged(string scalarPropertyName)
{
if (null != _complexChangeTracker)
{
_complexChangeTracker.EntityComplexMemberChanged(_rootComplexPropertyName,
this, scalarPropertyName);
}
}
}
[EdmComplexTypeAttribute(NamespaceName = "Microsoft.Samples.Edm", Name = "OrderInfo")]
public partial class OrderInfo : ComplexTypeChangeTracker
{
private string _orderNumber;
private string _purchaseOrder;
private string _accountNumber;
private string _comment;
override public void SetComplexChangeTracker(string rootComplexPropertyName, IEntityChangeTracker changeTracker)
{
// Call SetChangeTracker on the base class to set the change tracker
// and the name of the root complex type property on the entity.
base.SetComplexChangeTracker(rootComplexPropertyName, changeTracker);
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public string OrderNumber
{
get
{
return _orderNumber;
}
set
{
// Validate the value before setting it.
if (value.Length > 25)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidString,
new string[3] { value, "OrderNumber", "25" }));
}
// Report the change if the change tracker exists.
if (_complexChangeTracker != null)
{
ReportMemberChanging("OrderNumber");
_orderNumber = value;
ReportMemberChanged("OrderNumber");
}
else
{
_orderNumber = value;
}
}
}
[EdmScalarPropertyAttribute()]
public string PurchaseOrder
{
get
{
return _purchaseOrder;
}
set
{
// Validate the value before setting it.
if ((value != null) && value.Length > 25)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidString,
new string[3] { value, "PurchaseOrder", "25" }));
}
if (_purchaseOrder != value)
{
// Report the change if the change tracker exists.
if (_complexChangeTracker != null)
{
ReportMemberChanging("PurchaseOrder");
_purchaseOrder = value;
ReportMemberChanged("PurchaseOrder");
}
else
{
_purchaseOrder = value;
}
}
}
}
[EdmScalarPropertyAttribute()]
public string AccountNumber
{
get
{
return _accountNumber;
}
set
{
// Validate the value before setting it.
if ((value != null) && value.Length > 15)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidString,
new string[3] { value, "AccountNumber", "15" }));
}
if (_purchaseOrder != value)
{
// Report the change if the change tracker exists.
if (_complexChangeTracker != null)
{
ReportMemberChanging("AccountNumber");
_accountNumber = value;
ReportMemberChanged("AccountNumber");
}
else
{
_accountNumber = value;
}
}
}
}
[EdmScalarPropertyAttribute()]
public string Comment
{
get
{
return _comment;
}
set
{
// Validate the value before setting it.
if ((value != null) && value.Length > 128)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidString,
new string[3] { value, "Comment", "128" }));
}
if (_comment != value)
{
// Report the change if the change tracker exists.
if (_complexChangeTracker != null)
{
ReportMemberChanging("Comment");
_comment = value;
ReportMemberChanged("Comment");
}
else
{
_comment = value;
}
}
}
}
}
[EdmEntityTypeAttribute(NamespaceName = "Microsoft.Samples.Edm",
Name = "LineItem")]
public class LineItem : IEntityWithRelationships,
IEntityWithChangeTracker, IEntityWithKey
{
// Define private property variables.
int _lineItemId;
string _trackingNumber;
short _quantity;
int _product;
decimal _price;
decimal _discount;
decimal _total;
IEntityChangeTracker _changeTracker = null;
// Specify the IEntityChangeTracker to use for tracking changes.
void IEntityWithChangeTracker.SetChangeTracker(IEntityChangeTracker changeTracker)
{
_changeTracker = changeTracker;
}
EntityKey _entityKey = null;
// Define the EntityKey property for the class.
EntityKey IEntityWithKey.EntityKey
{
get
{
return _entityKey;
}
set
{
// Set the EntityKey property, if it is not set.
// Changing an existing value will cause an exception.
if (_entityKey == null)
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging(StructuralObject.EntityKeyPropertyName);
_entityKey = value;
_changeTracker.EntityMemberChanged(StructuralObject.EntityKeyPropertyName);
}
else
{
_entityKey = value;
}
}
}
}
RelationshipManager _relationships = null;
// Define a relationship manager for the class.
RelationshipManager IEntityWithRelationships.RelationshipManager
{
get
{
if (null == _relationships)
_relationships = RelationshipManager.Create(this);
return _relationships;
}
}
// Defines a navigation property to the Order class.
[EdmRelationshipNavigationPropertyAttribute("Microsoft.Samples.Edm", "FK_LineItem_Order_OrderId", "Order")]
public Order Order
{
get
{
return ((IEntityWithRelationships)(this)).RelationshipManager.
GetRelatedReference<Order>("FK_LineItem_Order_OrderId", "Order").Value;
}
set
{
((IEntityWithRelationships)(this)).RelationshipManager.
GetRelatedReference<Order>("FK_LineItem_Order_OrderId", "Order").Value = value;
}
}
[EdmScalarPropertyAttribute(EntityKeyProperty = true, IsNullable = false)]
public int LineItemId
{
get
{
return _lineItemId;
}
set
{
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("LineItemId");
_lineItemId = value;
_changeTracker.EntityMemberChanged("LineItemId");
}
else
{
_lineItemId = value;
}
}
}
[EdmScalarPropertyAttribute()]
public string TrackingNumber
{
get
{
return _trackingNumber;
}
set
{
if (_trackingNumber != value)
{
// Validate the value before setting it.
if (value.Length > 25)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidString,
new string[3] {value,"TrackingNumber", "25"}));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("TrackingNumber");
_trackingNumber = value;
_changeTracker.EntityMemberChanged("TrackingNumber");
}
else
{
_trackingNumber = value;
}
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public short Quantity
{
get
{
return _quantity;
}
set
{
if (_quantity != value)
{
// Validate the value before setting it.
if (value < 1)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Quantity" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Quantity");
_quantity = value;
_changeTracker.EntityMemberChanged("Quantity");
}
else
{
_quantity = value;
}
// Update the line total.
CalculateLineTotal();
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public int Product
{
get
{
return _product;
}
set
{
// Validate the value before setting it.
if (value < 1)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Product" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Product");
_product = value;
_changeTracker.EntityMemberChanged("Product");
}
else
{
_product = value;
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public decimal Price
{
get
{
return _price;
}
set
{
if (_price != value)
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Price" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Price");
_price = value;
_changeTracker.EntityMemberChanged("Price");
}
else
{
_price = value;
}
// Update the line total.
CalculateLineTotal();
}
}
}
[EdmScalarPropertyAttribute(IsNullable = false)]
public decimal Discount
{
get
{
return _discount;
}
set
{
// Validate the value before setting it.
if (value < 0)
{
throw new ApplicationException(string.Format(
Properties.Resources.propertyNotValidNegative,
new string[2] { value.ToString(), "Discount" }));
}
// Report the change if the change tracker exists.
if (_changeTracker != null)
{
_changeTracker.EntityMemberChanging("Discount");
_discount = value;
_changeTracker.EntityMemberChanged("Discount");
}
else
{
_discount = value;
}
}
}
public decimal Total
{
get
{
return _total;
}
}
private void CalculateLineTotal()
{
_total = (_quantity * (_price - _discount));
}
}
}
Siehe auch
Aufgaben
Weitere Ressourcen
Arbeiten mit benutzerdefinierten Objekten (Entity Framework-Aufgaben)