internal override void AddToLocalCache(IEntityWrapper wrappedEntity, bool applyConstraints) { if (wrappedEntity == this._wrappedCachedValue) { return; } TransactionManager transactionManager = this.ObjectContext != null ? this.ObjectContext.ObjectStateManager.TransactionManager : (TransactionManager)null; if (applyConstraints && this._wrappedCachedValue.Entity != null && (transactionManager == null || transactionManager.ProcessedEntities == null || transactionManager.ProcessedEntities.Contains(this._wrappedCachedValue))) { throw new InvalidOperationException(Strings.EntityReference_CannotAddMoreThanOneEntityToEntityReference((object)this.RelationshipNavigation.To, (object)this.RelationshipNavigation.RelationshipName)); } if (transactionManager != null) { if (wrappedEntity.Entity != null) { transactionManager.BeginRelatedEndAdd(); } } try { this.ClearCollectionOrRef((IEntityWrapper)null, (RelationshipNavigation)null, false); this._wrappedCachedValue = wrappedEntity; this._cachedValue = (TEntity)wrappedEntity.Entity; } finally { if (transactionManager != null && transactionManager.IsRelatedEndAdd) { transactionManager.EndRelatedEndAdd(); } } }
/// <summary> /// AddToLocalEnd is used by both APIs a) RelatedEnd.Add b) Value property setter. /// ApplyConstraints is true in case of RelatedEnd.Add because one cannot add entity to ref it its already set /// however applyConstraints is false in case of Value property setter because value can be set to a new value /// even if its non null. /// </summary> internal override void AddToLocalCache(IEntityWrapper wrappedEntity, bool applyConstraints) { if (wrappedEntity != _wrappedCachedValue) { TransactionManager tm = ObjectContext != null ? ObjectContext.ObjectStateManager.TransactionManager : null; if (applyConstraints && null != _wrappedCachedValue.Entity) { // The idea here is that we want to throw for constraint violations in things that we are bringing in, // but not when replacing references of things already in the context. Therefore, if the the thing that // we're replacing is in ProcessedEntities it means we're bringing it in and we should throw. if (tm == null || tm.ProcessedEntities == null || tm.ProcessedEntities.Contains(_wrappedCachedValue)) { throw EntityUtil.CannotAddMoreThanOneEntityToEntityReference(this.RelationshipNavigation.To, this.RelationshipNavigation.RelationshipName); } } if (tm != null && wrappedEntity.Entity != null) { // Setting this flag will prevent the FK from being temporarily set to null while changing // it from one value to the next. tm.BeginRelatedEndAdd(); } try { ClearCollectionOrRef(null, null, false); _wrappedCachedValue = wrappedEntity; _cachedValue = (TEntity)wrappedEntity.Entity; } finally { if (tm != null && tm.IsRelatedEndAdd) { tm.EndRelatedEndAdd(); } } } }