internal override void VerifyMultiplicityConstraintsForAdd(bool applyConstraints) { if (applyConstraints && !this.IsEmpty()) { throw EntityUtil.CannotAddMoreThanOneEntityToEntityReference(this.RelationshipNavigation.To, this.RelationshipNavigation.RelationshipName); } }
internal override void VerifyNavigationPropertyForAdd(IEntityWrapper wrapper) { if (this.TargetAccessor.HasProperty) { object value = WrappedOwner.GetNavigationPropertyValue(this); if (!Object.ReferenceEquals(null, value) && !Object.Equals(value, wrapper.Entity)) { throw EntityUtil.CannotAddMoreThanOneEntityToEntityReference( this.RelationshipNavigation.To, this.RelationshipNavigation.RelationshipName); } } }
/// <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(); } } } }