'------------------------------------------------------------------------------
'
' This code was generated from a template.
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
'
'------------------------------------------------------------------------------
Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.ComponentModel
Imports System.Globalization
Imports System.Runtime.Serialization
Imports System.Runtime.CompilerServices
' Helper class that captures most of the change tracking work that needs to be done
' for self tracking entities.
Public Class ObjectChangeTracker
#Region "Fields"
Private _isDeserializing As Boolean
Private _objectState As ObjectState = ObjectState.Added
Private _originalValues As OriginalValuesDictionary
Private _extendedProperties As ExtendedPropertiesDictionary
Private _changeTrackingEnabled As Boolean
Private _objectsAddedToCollections As New ObjectsAddedToCollectionProperties()
Private _objectsRemovedFromCollections As New ObjectsRemovedFromCollectionProperties()
#End Region
#Region "Events"
Public Event ObjectStateChanging As EventHandler(Of ObjectStateChangingEventArgs)
#End Region
Protected Overridable Sub OnObjectStateChanging(ByVal newState As ObjectState)
RaiseEvent ObjectStateChanging(Me, New ObjectStateChangingEventArgs With {.NewState = newState})
End Sub
Public Property State() As ObjectState
Get
Return _objectState
End Get
Set(ByVal value As ObjectState)
If _isDeserializing Or _changeTrackingEnabled Then
OnObjectStateChanging(value)
_objectState = value
End If
End Set
End Property
Public Property ChangeTrackingEnabled() As Boolean
Get
Return _changeTrackingEnabled
End Get
Set(ByVal value As Boolean)
_changeTrackingEnabled = value
End Set
End Property
' Returns the removed objects to collection valued properties that were changed.
Public ReadOnly Property ObjectsRemovedFromCollectionProperties() As ObjectsRemovedFromCollectionProperties
Get
If _objectsRemovedFromCollections Is Nothing Then
_objectsRemovedFromCollections = New ObjectsRemovedFromCollectionProperties()
End If
Return _objectsRemovedFromCollections
End Get
End Property
' Returns the original values for properties that were changed.
Public ReadOnly Property OriginalValues() As OriginalValuesDictionary
Get
If _originalValues Is Nothing Then
_originalValues = New OriginalValuesDictionary()
End If
Return _originalValues
End Get
End Property
' Returns the extended property values.
' This includes key values for independent associations that are needed for the
' concurrency model in the Entity Framework
Public ReadOnly Property ExtendedProperties() As ExtendedPropertiesDictionary
Get
If _extendedProperties Is Nothing Then
_extendedProperties = New ExtendedPropertiesDictionary()
End If
Return _extendedProperties
End Get
End Property
' Returns the added objects to collection valued properties that were changed.
Public ReadOnly Property ObjectsAddedToCollectionProperties() As ObjectsAddedToCollectionProperties
Get
If _objectsAddedToCollections Is Nothing Then
_objectsAddedToCollections = New ObjectsAddedToCollectionProperties()
End If
Return _objectsAddedToCollections
End Get
End Property
#Region "MethodsForChangeTrackingOnClient"
Public Sub OnDeserializingMethod(ByVal context As StreamingContext)
_isDeserializing = True
End Sub
Public Sub OnDeserializedMethod(ByVal context As StreamingContext)
_isDeserializing = False
End Sub
' Resets the ObjectChangeTracker to the Unchanged state and
' clears the original values as well as the record of changes
' to collection properties
Public Sub AcceptChanges()
OnObjectStateChanging(ObjectState.Unchanged)
OriginalValues.Clear()
ObjectsAddedToCollectionProperties.Clear()
ObjectsRemovedFromCollectionProperties.Clear()
ChangeTrackingEnabled = True
_objectState = ObjectState.Unchanged
End Sub
' Captures the original value for a property that is changing.
Friend Sub RecordOriginalValue(ByVal propertyName As String, ByVal value As Object)
If _changeTrackingEnabled AndAlso _objectState <> ObjectState.Added Then
If Not Me.OriginalValues.ContainsKey(propertyName) Then
OriginalValues(propertyName) = value
End If
End If
End Sub
' Records an addition to collection valued properties on SelfTracking Entities.
Friend Sub RecordAdditionToCollectionProperties(ByVal propertyName As String, ByVal value As Object)
If _changeTrackingEnabled Then
' Add the entity back after deleting it, we should do nothing here then
If Me.ObjectsRemovedFromCollectionProperties.ContainsKey(propertyName) AndAlso Me.ObjectsRemovedFromCollectionProperties(propertyName).Contains(value) Then
Me.ObjectsRemovedFromCollectionProperties(propertyName).Remove(value)
If Me.ObjectsRemovedFromCollectionProperties(propertyName).Count = 0 Then
Me.ObjectsRemovedFromCollectionProperties.Remove(propertyName)
End If
Exit Sub
End If
If Not Me.ObjectsAddedToCollectionProperties.ContainsKey(propertyName) Then
ObjectsAddedToCollectionProperties(propertyName) = New ObjectList()
ObjectsAddedToCollectionProperties(propertyName).Add(value)
Else
ObjectsAddedToCollectionProperties(propertyName).Add(value)
End If
End If
End Sub
' Records a removal to collection valued properties on SelfTracking Entities.
Friend Sub RecordRemovalFromCollectionProperties(ByVal propertyName As String, ByVal value As Object)
If _changeTrackingEnabled Then
' Delete the entity back after adding it, we should do nothing here then
If Me.ObjectsAddedToCollectionProperties.ContainsKey(propertyName) AndAlso Me.ObjectsAddedToCollectionProperties(propertyName).Contains(value) Then
Me.ObjectsAddedToCollectionProperties(propertyName).Remove(value)
If Me.ObjectsAddedToCollectionProperties(propertyName).Count = 0 Then
Me.ObjectsAddedToCollectionProperties.Remove(propertyName)
End If
Exit Sub
End If
If Not Me.ObjectsRemovedFromCollectionProperties.ContainsKey(propertyName) Then
ObjectsRemovedFromCollectionProperties(propertyName) = New ObjectList()
ObjectsRemovedFromCollectionProperties(propertyName).Add(value)
Else
If Not ObjectsRemovedFromCollectionProperties(propertyName).Contains(value) Then
ObjectsRemovedFromCollectionProperties(propertyName).Add(value)
End If
End If
End If
End Sub
#End Region
End Class
#Region "EnumForObjectState"
Public Enum ObjectState
Unchanged = &H1
Added = &H2
Modified = &H4
Deleted = &H8
End Enum
#End Region
Public Class ObjectsAddedToCollectionProperties
Inherits Dictionary(Of String, ObjectList)
End Class
Public Class ObjectsRemovedFromCollectionProperties
Inherits Dictionary(Of String, ObjectList)
End Class
Public Class OriginalValuesDictionary
Inherits Dictionary(Of String, Object)
End Class
Public Class ExtendedPropertiesDictionary
Inherits Dictionary(Of String, Object)
End Class
Public Class ObjectList
Inherits List(Of Object)
End Class
' The interface is implemented by the self tracking entities that EF will generate.
' We will have an Adapter that converts this interface to the interface that the EF expects.
' The Adapter will live on the server side.
Public Interface IObjectWithChangeTracker
' Has all the change tracking information for the subgraph of a given object.
Property ChangeTracker() As ObjectChangeTracker
End Interface
Public Class ObjectStateChangingEventArgs
Inherits EventArgs
Private _NewState As ObjectState
Public Property NewState() As ObjectState
Get
Return _NewState
End Get
Set(ByVal value As ObjectState)
_NewState = value
End Set
End Property
End Class
Public Module ObjectWithChangeTrackerExtensions
Public Function MarkAsDeleted(Of T As IObjectWithChangeTracker)(ByVal trackingItem As T) As T
If trackingItem Is Nothing Then
Throw New ArgumentNullException("trackingItem")
End If
trackingItem.ChangeTracker.ChangeTrackingEnabled = True
trackingItem.ChangeTracker.State = ObjectState.Deleted
Return trackingItem
End Function
Public Function MarkAsAdded(Of T As IObjectWithChangeTracker)(ByVal trackingItem As T) As T
If trackingItem Is Nothing Then
Throw New ArgumentNullException("trackingItem")
End If
trackingItem.ChangeTracker.ChangeTrackingEnabled = True
trackingItem.ChangeTracker.State = ObjectState.Added
Return trackingItem
End Function
Public Function MarkAsModified(Of T As IObjectWithChangeTracker)(ByVal trackingItem As T) As T
If trackingItem Is Nothing Then
Throw New ArgumentNullException("trackingItem")
End If
trackingItem.ChangeTracker.ChangeTrackingEnabled = True
trackingItem.ChangeTracker.State = ObjectState.Modified
Return trackingItem
End Function
Public Function MarkAsUnchanged(Of T As IObjectWithChangeTracker)(ByVal trackingItem As T) As T
If trackingItem Is Nothing Then
Throw New ArgumentNullException("trackingItem")
End If
trackingItem.ChangeTracker.ChangeTrackingEnabled = True
trackingItem.ChangeTracker.State = ObjectState.Unchanged
Return trackingItem
End Function
Public Sub StartTracking(ByVal trackingItem As IObjectWithChangeTracker)
If trackingItem Is Nothing Then
Throw New ArgumentNullException("trackingItem")
End If
trackingItem.ChangeTracker.ChangeTrackingEnabled = True
End Sub
Public Sub StopTracking(ByVal trackingItem As IObjectWithChangeTracker)
If trackingItem Is Nothing Then
Throw New ArgumentNullException("trackingItem")
End If
trackingItem.ChangeTracker.ChangeTrackingEnabled = False
End Sub
Public Sub AcceptChanges(ByVal trackingItem As IObjectWithChangeTracker)
If trackingItem Is Nothing Then
Throw New ArgumentNullException("trackingItem")
End If
trackingItem.ChangeTracker.AcceptChanges()
End Sub
End Module
' An System.Collections.ObjectModel.ObservableCollection that raises
' individual item removal notifications on clear and prevents adding duplicates.
Public Class TrackableCollection(Of T)
Inherits ObservableCollection(Of T)
Protected Overrides Sub ClearItems()
Dim items As New List(Of T)(Me)
items.ForEach(Function(t) Remove(t))
End Sub
Protected Overloads Overrides Sub InsertItem(ByVal index As Integer, ByVal item As T)
If Not Me.Contains(item) Then
MyBase.InsertItem(index, item)
End If
End Sub
End Class
' An interface that provides an event that fires when complex properties change.
' Changes can be the replacement of a complex property with a new complex type instance or
' a change to a scalar property within a complex type instance.
Public Interface INotifyComplexPropertyChanging
Event ComplexPropertyChanging As EventHandler
End Interface
Public Module EqualityComparer
' Helper method to determine if two byte arrays are the same value even if they are different object references
Public Function BinaryEquals(ByVal binaryValue1 As Object, ByVal binaryValue2 As Object) As Boolean
If Object.ReferenceEquals(binaryValue1, binaryValue2) Then
Return True
End If
Dim array1 As Byte() = TryCast(binaryValue1, Byte())
Dim array2 As Byte() = TryCast(binaryValue2, Byte())
If array1 IsNot Nothing AndAlso array2 IsNot Nothing Then
If array1.Length <> array2.Length Then
Return False
End If
For i As Integer = 0 To array1.Length - 1
If array1(i) <> array2(i) Then
Return False
End If
Next
Return True
End If
Return False
End Function
End Module