Implementar interfaces de clases de datos personalizadas (Entity Framework)
La manera recomendada de usar clases de datos personalizadas con un modelo Entity Data Model (EDM) es heredar de EntityObject y ComplexObject. En los casos en los que no se puede heredar de EntityObject y ComplexObject, o cuando se necesita un grado más alto de independencia del marco de trabajo, Entity Framework proporciona un conjunto de interfaces de clases de datos personalizadas. Si no hereda de EntityObject, debe implementar estas interfaces para usar clases de datos personalizadas con un EDM. Las interfaces concretas que implemente dependerán de los requisitos de las clases de datos personalizadas y de su aplicación.
IEntityWithChangeTracker
Se requiere para el seguimiento de cambios. Permite que Servicios de objeto realice el seguimiento de los cambios en el objeto.Servicios de objeto proporciona objetos con la interfaz IEntityChangeTracker a fin de habilitar los objetos para notificar los cambios. IEntityWithChangeTracker define el método SetChangeTracker. Este método especifica el IEntityChangeTracker que se utiliza para notificar los cambios. Para obtener más información, vea Notificar los cambios en clases de datos personalizadas (Entity Framework).
IEntityWithKey
Opcional. Expone la clave de entidad de Servicios de objeto para mejorar el rendimiento.IEntityWithKey define la propiedad EntityKey. Servicios de objeto usa la propiedad EntityKey para administrar objetos en el contexto del objeto.
Si elige no implementar IEntityWithKey, observará que el rendimiento disminuye y el uso de memoria aumenta al cargar los objetos relacionados, al asociar los objetos a un contexto del objeto o al realizar cualquier operación que requiera una clave.
IEntityWithRelationships
Se requiere para las entidades con asociaciones. Habilita Servicios de objeto para administrar las relaciones entre los objetos.IEntityWithRelationships define la propiedad RelationshipManager. Servicios de objeto usa la propiedad RelationshipManager para tener acceso al RelationshipManager que se usa para administrar las relaciones con otros objetos.
Para obtener más información, vea Cómo implementar interfaces de clases de datos personalizadas (Entity Framework).
Al igual que las clases de datos personalizadas que heredan de EntityObject, las clases que implementan estas interfaces deben cumplir los requisitos siguientes:
Debe haber un objeto para cada tipo de entidad que está definido en el archivo de lenguaje de definición de esquemas conceptuales (CSDL).
El espacio de nombres, las clases y las propiedades de datos deben tener aplicados los atributos de EDM adecuados.
Los nombres del espacio de nombres, las clases y las propiedades de datos que tienen aplicados los atributos de EDM deben coincidir con los nombres del archivo CSDL correspondiente.
Para obtener más información, vea Personalizar objetos (Entity Framework).
En el ejemplo siguiente se muestra el código que se requiere para implementar estas interfaces para un objeto Order, donde Order está basado en la tabla SalesOrderHeader.
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
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;
}
}
Tipos complejos
Los tipos complejos son propiedades no escalares de tipos de entidad que permiten organizar las propiedades escalares dentro de las entidades. Para obtener más información, vea Tipo complejo (EDM). El seguimiento de los cambios en los objetos de tipos complejos requiere que se escriba código de seguimiento de cambios personalizado. Por lo tanto, se recomienda heredar de EntityObject y ComplexObject cuando sea posible. No hay ninguna interfaz de clase de datos personalizada que implementar para los objetos de tipos complejos. Sin embargo, puede utilizar el procedimiento siguiente para implementar el seguimiento de cambios con objetos de tipos complejos que no hereden de ComplexObject.
![]() |
---|
Si decide implementar las interfaces de clases de datos personalizadas para los objetos pero también para heredar de ComplexObject, debe seguir implementando el seguimiento de cambios personalizado según se describe en el procedimiento siguiente. |
Para implementar el seguimiento de cambios en los objetos de tipos complejos
Implemente interfaces de datos personalizadas para los tipos de entidad. Para obtener más información, vea Cómo implementar interfaces de clases de datos personalizadas (Entity Framework).
Asegúrese de que los tipos complejos se definen correctamente en las secciones conceptual y de asignación del EDM. Para obtener más información, vea Tipo complejo (EDM).
Defina una clase base abstracta denominada ComplexTypeChangeTracker.
' 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
// 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); } } }
Defina la clase de tipo complejo, que hereda de ComplexTypeChangeTracker, y aplique el EdmComplexTypeAttribute.
<EdmComplexTypeAttribute(NamespaceName:="Microsoft.Samples.Edm", Name:="OrderInfo")> _ Partial Public Class OrderInfo Inherits ComplexTypeChangeTracker
[EdmComplexTypeAttribute(NamespaceName = "Microsoft.Samples.Edm", Name = "OrderInfo")] public partial class OrderInfo : ComplexTypeChangeTracker {
En la clase del tipo complejo, invalide el método SetComplexChangeTracker.
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
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); }
Implemente el seguimiento de cambios estándar en las propiedades escalares del tipo complejo. Para obtener más información, vea Notificar los cambios en clases de datos personalizadas (Entity Framework).
Aplique el EdmComplexPropertyAttribute a la propiedad compleja en el tipo de entidad y agregue una llamada a SetComplexChangeTracker para restablecer el seguidor de cambios cuando la propiedad compleja cambie.
<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
[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); } } }
Repita los pasos 4 a 7 con cada propiedad compleja.
En la implementación de System.Data.Objects.DataClasses.IEntityWithChangeTracker.SetChangeTracker(System.Data.Objects.DataClasses.IEntityChangeTracker) para el tipo de entidad, inserte una llamada a SetComplexChangeTracker para establecer el seguidor de cambios. Haga esto una vez con cada propiedad compleja del tipo.
' 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
// Every time the change tracker is set, we must also set all the // complex type change trackers. if (_extendedInfo != null) { _extendedInfo.SetComplexChangeTracker("ExtendedInfo", _changeTracker); }
Vea también
Referencia
Conceptos
Información general de Servicios de objeto (Entity Framework)