Реализация интерфейсов пользовательских классов данных (платформа Entity Framework)
Рекомендуемым способом применения пользовательских классов данных с моделью EDM является наследование от классов EntityObject и ComplexObject. В тех случаях, когда наследование от классов EntityObject и ComplexObject невозможно или необходима более высокая степень независимости от платформы, Entity Framework предоставляет набор интерфейсов пользовательских классов данных. При отсутствии наследования от класса EntityObject необходимо реализовать эти интерфейсы, чтобы использовать с моделью EDM пользовательские классы данных. Реализация конкретных интерфейсов зависит от требований пользовательских классов данных и приложения.
IEntityWithChangeTracker
Требуется для отслеживания изменений. Задействует службы объектов для отслеживания изменений объекта.Службы объектов предоставляют объектам интерфейс IEntityChangeTracker для их включения в отчеты об изменениях. ИнтерфейсIEntityWithChangeTracker определяет метод SetChangeTracker. Этот метод задает интерфейс IEntityChangeTracker, который используется в отчете об изменениях. Дополнительные сведения см. в разделе Отчеты об изменениях в пользовательских классах данных (платформа Entity Framework).
IEntityWithKey
Необязательный. Предоставляет ключ сущности службам объектов для повышения производительности.Интерфейс IEntityWithKey определяет свойство EntityKey. Службы объектов используют свойство EntityKey для управления объектами в контексте объекта.
Если принято решение отказаться от реализации интерфейса IEntityWithKey, то это приведет к снижению производительности и повышению расхода памяти при загрузке связанных объектов, присоединении объектов к контексту объекта и любых других операциях, для которых необходим ключ.
IEntityWithRelationships
Требуется для сущностей с ассоциациями. Задействует службы объектов в управлении связями между объектами.Интерфейс IEntityWithRelationships определяет свойство RelationshipManager. Службы объектов используют свойство RelationshipManager для доступа к сущности RelationshipManager, применяемой для управления связями с другими объектами.
Дополнительные сведения см. в разделе Как реализовать пользовательские классы данных (платформа Entity Framework).
Как и пользовательские классы данных, наследованные от класса EntityObject, классы, реализующие эти интерфейсы, должны отвечать следующим требованиям.
Должен существовать объект для каждого типа сущности, определенного в CSDL-файле.
К пространству имен, классам и свойствам данных необходимо применить соответствующие атрибуты модели EDM.
Имена пространства имен, классов и свойств данных с примененными атрибутами модели EDM должны соответствовать именам в соответствующем CSDL-файле.
Дополнительные сведения см. в разделе Настройка объектов (платформа Entity Framework).
В приведенных ниже примерах показан код, необходимый для реализации этих интерфейсов для объекта Order, основанного на таблице 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;
}
}
Сложные типы
Сложные типы — это нескалярные свойства типов сущностей, которые позволяют организовать в сущностях скалярные свойства. Дополнительные сведения см. в разделе Сложный тип (модель EDM). Отслеживание изменений в сложных типах требует написания пользовательского кода для отслеживания изменений. Поэтому рекомендуется применять наследование от EntityObject и ComplexObject, если это возможно. Для объектов сложного типа не существует реализуемых интерфейсов пользовательских классов данных. Однако для реализации отслеживания изменений в сложных типах, не наследованных от класса ComplexObject, можно использовать следующую процедуру.
Примечание. |
---|
Если нужно реализовать интерфейсы пользовательских классов данных для объектов и одновременно наследовать от класса ComplexObject, необходимо реализовать пользовательское отслеживание изменений, как показано в следующей процедуре. |
Реализация пользовательского отслеживания изменений для объектов сложного типа
Реализуйте интерфейсы пользовательских классов данных для типов сущностей. Дополнительные сведения см. в разделе Как реализовать пользовательские классы данных (платформа Entity Framework).
Убедитесь, что сложные типы верно определены в концептуальном разделе и разделе сопоставлений модели EDM. Дополнительные сведения см. в разделе Сложный тип (модель EDM).
Определите абстрактный базовый класс с именем 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); } } }
Определите класс сложного типа, наследуемый от класса ComplexTypeChangeTracker, и примените атрибут 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 {
В классе сложного типа переопределите метод 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); }
Реализуйте стандартное отслеживание изменений в скалярных свойствах сложного типа. Дополнительные сведения см. в разделе Отчеты об изменениях в пользовательских классах данных (платформа Entity Framework).
Присвойте сложному свойству в типе сущности атрибут EdmComplexPropertyAttribute и добавьте вызов метода SetComplexChangeTracker для перезапуска объекта отслеживания изменений при изменении этого сложного свойства.
<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); } } }
Повторите шаги 4–7 для каждого сложного свойства.
В реализацию интерфейса System.Data.Objects.DataClasses.IEntityWithChangeTracker.SetChangeTracker(System.Data.Objects.DataClasses.IEntityChangeTracker) для типа сущности вставьте вызов метода SetComplexChangeTracker для установки объекта отслеживания изменений. Повторите эту операцию для каждого сложного свойства в типе.
' 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); }
См. также
Справочник
Генератор модели EDM (EdmGen.exe)
Основные понятия
Общие сведения о службах объектов (платформа Entity Framework)