protected override void UpdateRelatedEndInternal( CustomObjectContext objectContext, RelatedEndEntityObject relatedEntityObject, CustomStoreOperationKind changeKind ) { if (CustomStoreOperationKind.Add == changeKind) { if (null != RelationshipMetadata.To.RelatedProperty) { RelationshipMetadata.To.RelatedProperty.SetValue(relatedEntityObject, _thisEndObject); } if (null != objectContext) { objectContext.AddObject(RelationshipMetadata.To.EntitySetType.Name, relatedEntityObject); } } else { Debug.Assert(CustomStoreOperationKind.Delete == changeKind); if (null != RelationshipMetadata.To.RelatedProperty) { RelationshipMetadata.To.RelatedProperty.SetValue(relatedEntityObject, null); } if (null != objectContext) { objectContext.DeleteObject(relatedEntityObject); } } }
public override void CascadeStoreOperation(CustomStoreOperationKind changeKind) { CustomObjectContext context = ObjectContextWeakRef.Target; Debug.Assert(null != context); Queue <object> objectsToBeRemoved = null; foreach (object entityObject in this) { if (CustomStoreOperationKind.Add == changeKind) { context.AddObject(RelationshipMetadata.To.EntitySetType.Name, entityObject); } else if (CustomStoreOperationKind.Delete == changeKind) { if (null == objectsToBeRemoved) { objectsToBeRemoved = new Queue <object>(); } objectsToBeRemoved.Enqueue(entityObject); } } if (null != objectsToBeRemoved && objectsToBeRemoved.Count > 0) { foreach (object entityObject in objectsToBeRemoved) { Remove(entityObject); DeleteObjectIfTransietOrphan(context, entityObject); } } }
protected override void OnChangeCompleted( object relatedEntityObject, CustomStoreOperationKind changeKind ) { base.OnChangeCompleted(relatedEntityObject, changeKind); if (null != ObjectContextWeakRef) { Debug.Assert(relatedEntityObject is EntityObjectType); CustomObjectContext objectContext = ObjectContextWeakRef.Target; if (null != objectContext && null != RelationshipMetadata) { var thisRelationshipEnd = new CustomRelationshipEnd(_thisEndEntityObject, RelationshipMetadata.From); if (objectContext.RelationshipHelper.IsVisitedRelationshipEnd(thisRelationshipEnd)) { return; } try { objectContext.RelationshipHelper.AddToVisitedRelationshipEnds(thisRelationshipEnd); UpdateRelatedEndInternal(objectContext, (EntityObjectType)relatedEntityObject, changeKind); } finally { objectContext.RelationshipHelper.RemoveFromVisitedRelationshipEnds(thisRelationshipEnd); } } } }
protected virtual void ValidateStateTransitionInternal( CustomObjectContext objectContext, EntityObjectType relatedEntityObject, CustomStoreOperationKind changeKind ) { }
protected void ValidateStateTransition( EntityObjectType relatedEntityObject, CustomStoreOperationKind changeKind ) { if (null != ObjectContextWeakRef) { CustomObjectContext objectContext = ObjectContextWeakRef.Target; if (null != objectContext && null != RelationshipMetadata) { var thisRelationshipEnd = new CustomRelationshipEnd(_thisEndEntityObject, RelationshipMetadata.From); if (objectContext.RelationshipHelper.IsVisitedRelationshipEnd(thisRelationshipEnd)) { return; } try { objectContext.RelationshipHelper.AddToVisitedRelationshipEnds(thisRelationshipEnd); ValidateStateTransitionInternal(objectContext, relatedEntityObject, changeKind); } finally { objectContext.RelationshipHelper.RemoveFromVisitedRelationshipEnds(thisRelationshipEnd); } } } }
public void AttachToContext(CustomObjectContext objectContext) { if (!((ICustomRelationshipManager)this).IsAttachedToContext(objectContext)) { _objectContextWeakRef = new WeakReference <CustomObjectContext>(objectContext); } }
protected override void UpdateRelatedEndInternal( CustomObjectContext objectContext, RelatedEndEntityObject relatedEntityObject, CustomStoreOperationKind changeKind ) { if (CustomStoreOperationKind.Add == changeKind) { if (null != RelationshipMetadata.To.RelatedProperty) { object relatedManyToManyCollection = RelationshipMetadata.To.RelatedProperty.GetValue(relatedEntityObject); Debug.Assert(null != relatedManyToManyCollection); if (relatedManyToManyCollection is CustomObjectCollectionBase) { Debug.Assert(relatedManyToManyCollection is CustomObjectCollectionBase); var managedManyToManyCollection = (CustomObjectCollectionBase)relatedManyToManyCollection; managedManyToManyCollection.Add(_thisEndObject); } else { MethodInfo addMethod = relatedManyToManyCollection.GetType().GetMethod("Add"); Debug.Assert(null != addMethod); addMethod.Invoke(relatedManyToManyCollection, new object[] { _thisEndObject }); } } if (null != objectContext) { objectContext.AddObject(RelationshipMetadata.To.EntitySetType.Name, relatedEntityObject); } } else { Debug.Assert(CustomStoreOperationKind.Delete == changeKind); if (null != RelationshipMetadata.To.RelatedProperty) { object relatedManyToManyCollection = RelationshipMetadata.To.RelatedProperty.GetValue(relatedEntityObject); if (relatedManyToManyCollection is CustomObjectCollectionBase) { Debug.Assert(relatedManyToManyCollection is CustomObjectCollectionBase); var managedManyToManyCollection = (CustomObjectCollectionBase)relatedManyToManyCollection; managedManyToManyCollection.Remove(_thisEndObject); } else { MethodInfo removeMethod = relatedManyToManyCollection.GetType().GetMethod("Remove"); Debug.Assert(null != removeMethod); removeMethod.Invoke(relatedManyToManyCollection, new object[] { _thisEndObject }); } if (null != objectContext) { DeleteObjectIfTransietOrphan(objectContext, relatedEntityObject); } } } }
private void DeleteObjectIfTransietOrphan(CustomObjectContext objectContext, object entityObject) { if (objectContext.RelationshipHelper.IsTransietObject(entityObject)) { // we just deleted an entity object that was not persited yet // if the object becomes "orphan" e.g. doesn't participate in // any other collection - delete it from the store // TODO: implement } }
public void PreAtachExistingDataObjects(CustomObjectContext objectContext) { if (!_defaultDataCreated) { CreateAndAttachDefaultDataObjects(objectContext); objectContext.SaveAllChanges(); _defaultDataCreated = true; } else { foreach (var entitySetEntry in _entitySetMap.Values) { foreach (object entityObject in entitySetEntry.EntityObjects) { objectContext.AddObject(entitySetEntry.EntitySetType.Name, entityObject); } } objectContext.AcceptAllChanges(); } }
public override void CascadeStoreOperation(CustomStoreOperationKind operationKind) { CustomObjectContext context = ObjectContextWeakRef.Target; Debug.Assert(null != context); foreach (object entityObject in this) { if (CustomStoreOperationKind.Add == operationKind) { context.AddObject(RelationshipMetadata.To.EntitySetType.Name, entityObject); } else if (CustomStoreOperationKind.Delete == operationKind) { context.DeleteObject(entityObject); } else { Debug.Fail("Unexpected store operation kind", operationKind.ToString()); } } }
protected override void ValidateStateTransitionInternal( CustomObjectContext objectContext, RelatedEndEntityObject relatedEntityObject, CustomStoreOperationKind changeKind ) { if (Object.ReferenceEquals(_thisEndObject, relatedEntityObject)) { throw new InvalidOperationException(String.Format( "Cannot add entity object '{0}' to its one one-to-many collection.", _thisEndObject )); } if (CustomStoreOperationKind.Add == changeKind) { if (null != RelationshipMetadata.To.RelatedProperty) { var sameOneEndRoleObject = RelationshipMetadata.To.RelatedProperty.GetValue(relatedEntityObject); if ( !Object.ReferenceEquals(sameOneEndRoleObject, null) && !Object.ReferenceEquals(sameOneEndRoleObject, _thisEndObject)) { #if _DO_NOT_REMOVE_SILENTLY_SAME_ROLE_INSTANCE throw new InvalidOperationException(String.Format( "Entity object '{0}' is already associated with another " + "instance '{1}' of principal end in the one-to-many relationship " + "between '{2}' and '{3}'.", relatedEntityObject, sameOneEndRoleObject, typeof(ThisEndEntityObject), typeof(RelatedEndEntityObject) )); #else CustomEntityType entityType = RelationshipMetadata.From.EntityType; // TODO: do we need this assert? saw it failing in Astoria tests; may be it is // caused by multiple object contexts loaded from the same data source? // in this implementation all object contexts share same objects #if _NOT_ASTORIA_TESTS Debug.Assert(entityType.ClrObjectType.IsAssignableFrom(sameOneEndRoleObject.GetType())); #endif object otherCollection = RelationshipMetadata.GetValue(sameOneEndRoleObject); Debug.Assert(null != otherCollection); if (otherCollection is CustomObjectCollectionBase) { bool removed = ((CustomObjectCollectionBase)otherCollection).Remove(relatedEntityObject); // TODO: need to investigate; saw a failure here with Northwind model in Astoria tests // same problem with many object contexts loaded from the same data source as above? #if _NOT_ASTORIA_TESTS Debug.Assert(removed); #endif } else { MethodInfo removeMethod = otherCollection.GetType().GetMethod("Remove"); Debug.Assert(null != removeMethod); removeMethod.Invoke(otherCollection, new object[] { relatedEntityObject }); } #endif } } } }
protected abstract void UpdateRelatedEndInternal( CustomObjectContext objectContext, EntityObjectType relatedEntityObject, CustomStoreOperationKind changeKind );
public bool IsAttachedToContext(CustomObjectContext objectContext) { return(null != _objectContextWeakRef && _objectContextWeakRef.IsAlive && Object.ReferenceEquals(_objectContextWeakRef.Target, objectContext)); }
protected virtual void CreateAndAttachDefaultDataObjects(CustomObjectContext objectContext) { }