/// <summary> /// Determine the best of the given targets for the next mining laser. /// </summary> /// <param name="chosenTargets"></param> /// <param name="activeModuleCountByTargetId"></param> /// <param name="intendedModuleCountByTargetId"></param> /// <returns></returns> private IEntityWrapper GetBestTargetForMiningLaser(IEnumerable <IEntityWrapper> chosenTargets, IDictionary <long, int> activeModuleCountByTargetId, IDictionary <long, int> intendedModuleCountByTargetId) { var methodName = "GetBestTargetForMiningLaser"; LogTrace(methodName); IEntityWrapper chosenTarget = null; foreach (var target in chosenTargets) { var activeModuleCount = activeModuleCountByTargetId[target.ID]; var intendedModuleCount = intendedModuleCountByTargetId[target.ID]; var neededModules = intendedModuleCount - activeModuleCount; if (neededModules <= 0) { continue; } chosenTarget = target; activeModuleCountByTargetId[target.ID]++; break; } return(chosenTarget); }
// <summary> // Disconnected removes are not supported for an EntityReference so we should report this as an error. // </summary> // <param name="wrappedEntity"> The entity to remove from the related end in a disconnected state. </param> internal override bool DisconnectedRemove(IEntityWrapper wrappedEntity) { DebugCheck.NotNull(wrappedEntity); CheckOwnerNull(); return(false); }
internal override void ClearCollectionOrRef(IEntityWrapper wrappedEntity, RelationshipNavigation navigation, bool doCascadeDelete) { if (null != _wrappedRelatedEntities) { //copy into list because changing collection member is not allowed during enumeration. // If possible avoid copying into list. var tempCopy = new List <IEntityWrapper>(_wrappedRelatedEntities.Values); foreach (var wrappedCurrent in tempCopy) { // Following condition checks if we have already visited this graph node. If its true then // we should not do fixup because that would cause circular loop if ((wrappedEntity.Entity == wrappedCurrent.Entity) && (navigation.Equals(RelationshipNavigation))) { Remove( wrappedCurrent, /*fixup*/ false, /*deleteEntity*/ false, /*deleteOwner*/ false, /*applyReferentialConstraints*/ false, /*preserveForeignKey*/ false); } else { Remove( wrappedCurrent, /*fixup*/ true, doCascadeDelete, /*deleteOwner*/ false, /*applyReferentialConstraints*/ false, /*preserveForeignKey*/ false); } } Debug.Assert( _wrappedRelatedEntities.Count == 0, "After removing all related entities local collection count should be zero"); } }
internal EntityKey ValidateOwnerWithRIConstraints(IEntityWrapper targetEntity, EntityKey targetEntityKey, bool checkBothEnds) { EntityKey ownerKey = WrappedOwner.EntityKey; // Check if Referential Constraints are violated if ((object)ownerKey != null && !ownerKey.IsTemporary && IsDependentEndOfReferentialConstraint(checkIdentifying: true)) { Debug.Assert(CachedForeignKey != null || EntityKey == null, "CachedForeignKey should not be null if EntityKey is not null."); ValidateSettingRIConstraints(targetEntity, targetEntityKey == null, (this.CachedForeignKey != null && this.CachedForeignKey != targetEntityKey)); } else if (checkBothEnds && targetEntity != null && targetEntity.Entity != null) { EntityReference otherEnd = GetOtherEndOfRelationship(targetEntity) as EntityReference; if (otherEnd != null) { otherEnd.ValidateOwnerWithRIConstraints(WrappedOwner, ownerKey, checkBothEnds: false); } } return(ownerKey); }
public IEntityWrapper HandleEntity <TEntity>( IEntityWrapper wrappedEntity, EntityKey entityKey, EntitySet entitySet) { IEntityWrapper wrappedEntity1 = wrappedEntity; if ((object)entityKey != null) { EntityEntry entityEntry = this.Context.ObjectStateManager.FindEntityEntry(entityKey); if (entityEntry != null && !entityEntry.IsKeyEntry) { this.UpdateEntry <TEntity>(wrappedEntity, entityEntry); wrappedEntity1 = entityEntry.WrappedEntity; } else { this.RegisterMaterializedEntityForEvent(wrappedEntity1); if (entityEntry == null) { this.Context.ObjectStateManager.AddEntry(wrappedEntity, entityKey, entitySet, nameof(HandleEntity), false); } else { this.Context.ObjectStateManager.PromoteKeyEntry(entityEntry, wrappedEntity, false, true, false); } } } return(wrappedEntity1); }
public bool IsRatTarget(IEntityWrapper entity) { //if it's not an npc, return false. if (entity.IsPC || !IsNpc(entity)) { return(false); } //If it's a celestial, station, or asteroid return false switch (entity.CategoryID) { case (int)CategoryIDs.Station: case (int)CategoryIDs.Celestial: case (int)CategoryIDs.Asteroid: case (int)CategoryIDs.Charge: return(false); } //If it's a collidable, jetcan, or spawn container, return false. switch (entity.GroupID) { case (int)GroupIDs.LargeCollidableObject: case (int)GroupIDs.LargeCollidableShip: case (int)GroupIDs.LargeCollidableStructure: case (int)GroupIDs.SpawnContainer: case (int)GroupIDs.CargoContainer: case (int)GroupIDs.DeadspaceOverseersStructure: case (int)GroupIDs.CombatDrone: case (int)GroupIDs.Orbital_Infrastructure: return(false); } return(true); }
internal void UpdateForeignKeyValues(IEntityWrapper dependentEntity, EntityKey principalKey) { ReferentialConstraint referentialConstraint = ((AssociationType)this.RelationMetadata).ReferentialConstraints[0]; ObjectStateManager objectStateManager = this.ObjectContext.ObjectStateManager; objectStateManager.TransactionManager.BeginForeignKeyUpdate(this); try { EntitySet entitySet = ((AssociationSet)this.RelationshipSet).AssociationSetEnds[this.FromEndMember.Name].EntitySet; StateManagerTypeMetadata managerTypeMetadata = objectStateManager.GetOrAddStateManagerTypeMetadata(dependentEntity.IdentityType, entitySet); for (int index = 0; index < referentialConstraint.FromProperties.Count; ++index) { object valueByName = principalKey.FindValueByName(referentialConstraint.FromProperties[index].Name); int olayerMemberName = managerTypeMetadata.GetOrdinalforOLayerMemberName(referentialConstraint.ToProperties[index].Name); object x = managerTypeMetadata.Member(olayerMemberName).GetValue(dependentEntity.Entity); if (!ByValueEqualityComparer.Default.Equals(x, valueByName)) { dependentEntity.SetCurrentValue(dependentEntity.ObjectStateEntry, managerTypeMetadata.Member(olayerMemberName), -1, dependentEntity.Entity, valueByName); } } this.SetCachedForeignKey(principalKey, dependentEntity.ObjectStateEntry); if (this.WrappedOwner.ObjectStateEntry == null) { return; } objectStateManager.ForgetEntryWithConceptualNull(this.WrappedOwner.ObjectStateEntry, false); } finally { objectStateManager.TransactionManager.EndForeignKeyUpdate(); } }
internal override bool CheckReferentialConstraintPrincipalProperty( EntityEntry ownerEntry, ReferentialConstraint constraint) { EntityKey principalKey; if (!this.IsEmpty()) { IEntityWrapper referenceValue = this.ReferenceValue; if (referenceValue.ObjectStateEntry != null && referenceValue.ObjectStateEntry.State == EntityState.Added) { return(true); } principalKey = this.ExtractPrincipalKey(referenceValue); } else { if (this.ToEndMember.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne && this.ToEndMember.RelationshipMultiplicity != RelationshipMultiplicity.One || !(this.DetachedEntityKey != (EntityKey)null)) { return(true); } principalKey = !this.IsForeignKey || this.ObjectContext.ObjectStateManager.TransactionManager.IsAddTracking || this.ObjectContext.ObjectStateManager.TransactionManager.IsAttachTracking ? this.DetachedEntityKey : this.EntityKey; } return(RelatedEnd.VerifyRIConstraintsWithRelatedEntry(constraint, new Func <string, object>(ownerEntry.GetCurrentEntityValue), principalKey)); }
internal EntityReference( IEntityWrapper wrappedOwner, RelationshipNavigation navigation, IRelationshipFixer relationshipFixer) : base(wrappedOwner, navigation, relationshipFixer) { }
internal override void VerifyType(IEntityWrapper wrappedEntity) { if (!CanSetEntityType(wrappedEntity)) { throw EntityUtil.InvalidContainedTypeReference(wrappedEntity.Entity.GetType().FullName, typeof(TEntity).FullName); } }
private void BreakAction(IEntityWrapper targetEntity) { var methodName = "BreakAction"; // ReSharper disable SpecifyACultureInStringConversionExplicitly LogTrace(methodName, "Target Entity: {0}", targetEntity == null ? "null" : targetEntity.ID.ToString()); // ReSharper restore SpecifyACultureInStringConversionExplicitly if (StealthBot.Movement.IsMoving) { StealthBot.Movement.StopCurrentMovement(true); } if (targetEntity == null) { return; } if (StealthBot.TargetQueue.IsQueued(targetEntity.ID)) { StealthBot.TargetQueue.DequeueTarget(targetEntity.ID); } if (targetEntity.IsLockedTarget) { targetEntity.UnlockTarget(); } }
/// <summary> /// Called to create a new wrapper outside of the normal materialization process. /// This method is typically used when a new entity is created outside the context and then is /// added or attached. The materializer bypasses this method and calls wrapper constructors /// directory for performance reasons. /// This method does not check whether or not the wrapper already exists in the context. /// </summary> /// <param name="entity">The entity for which a wrapper will be created</param> /// <param name="key">The key associated with that entity, or null</param> /// <returns>The new wrapper instance</returns> internal static IEntityWrapper CreateNewWrapper(object entity, EntityKey key) { Debug.Assert(!(entity is IEntityWrapper), "Object is an IEntityWrapper instance instead of the raw entity."); if (entity == null) { return(NullEntityWrapper.NullWrapper); } // We used a cache of functions based on the actual type of entity that we need to wrap. // Creatung these functions is slow, but once they are created they are relatively fast. IEntityWrapper wrappedEntity = _delegateCache.Evaluate(entity.GetType())(entity); wrappedEntity.RelationshipManager.SetWrappedOwner(wrappedEntity, entity); // We cast to object here to avoid calling the overridden != operator on EntityKey. // This creates a very small perf gain, which is none-the-less significant for lean no-tracking cases. if ((object)key != null && (object)wrappedEntity.EntityKey == null) { wrappedEntity.EntityKey = key; } // If the entity is a proxy, set the wrapper to match EntityProxyTypeInfo proxyTypeInfo; if (EntityProxyFactory.TryGetProxyType(entity.GetType(), out proxyTypeInfo)) { proxyTypeInfo.SetEntityWrapper(wrappedEntity); } return(wrappedEntity); }
internal EntityCollection( IEntityWrapper wrappedOwner, RelationshipNavigation navigation, IRelationshipFixer relationshipFixer) : base(wrappedOwner, navigation, relationshipFixer) { }
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(); } } }
internal override bool CheckIfNavigationPropertyContainsEntity(IEntityWrapper wrapper) { Debug.Assert(RelationshipNavigation != null, "null RelationshipNavigation"); // If the navigation property doesn't exist (e.g. unidirectional prop), then it can't contain the entity. if (!TargetAccessor.HasProperty) { return(false); } var value = WrappedOwner.GetNavigationPropertyValue(this); if (value != null) { var enumerable = value as IEnumerable; if (enumerable == null) { throw new EntityException( Strings.ObjectStateEntry_UnableToEnumerateCollection( TargetAccessor.PropertyName, WrappedOwner.Entity.GetType().FullName)); } foreach (var o in enumerable) { if (ReferenceEquals(o, wrapper.Entity)) { return(true); } } } return(false); }
/// <summary> /// Method called by proxy interceptor delegate to provide lazy loading behavior for navigation properties. /// </summary> /// <typeparam name="TItem">property type</typeparam> /// <param name="propertyValue">The property value whose associated relationship is to be loaded.</param> /// <param name="relationshipName">String name of the relationship.</param> /// <param name="targetRoleName">String name of the related end to be loaded for the relationship specified by <paramref name="relationshipName"/>.</param> /// <param name="wrapperObject">Entity wrapper object used to retrieve RelationshipManager for the proxied entity.</param> /// <returns> /// True if the value instance was mutated and can be returned /// False if the class should refetch the value because the instance has changed /// </returns> private static bool LoadProperty <TItem>(TItem propertyValue, string relationshipName, string targetRoleName, bool mustBeNull, object wrapperObject) where TItem : class { // Only attempt to load collection if: // // 1. Collection is non-null. // 2. ObjectContext.ContextOptions.LazyLoadingEnabled is true // 3. A non-null RelationshipManager can be retrieved (this is asserted). // 4. The EntityCollection is not already loaded. Debug.Assert(wrapperObject == null || wrapperObject is IEntityWrapper, "wrapperObject must be an IEntityWrapper"); IEntityWrapper wrapper = (IEntityWrapper)wrapperObject; // We want an exception if the cast fails. if (wrapper != null && wrapper.Context != null) { RelationshipManager relationshipManager = wrapper.RelationshipManager; Debug.Assert(relationshipManager != null, "relationshipManager should be non-null"); if (relationshipManager != null && (!mustBeNull || propertyValue == null)) { RelatedEnd relatedEnd = relationshipManager.GetRelatedEndInternal(relationshipName, targetRoleName); relatedEnd.DeferredLoad(); } } return(propertyValue != null); }
internal override void ClearCollectionOrRef( IEntityWrapper wrappedEntity, RelationshipNavigation navigation, bool doCascadeDelete) { if (wrappedEntity == null) { wrappedEntity = NullEntityWrapper.NullWrapper; } if (this._wrappedCachedValue.Entity != null) { if (wrappedEntity.Entity == this._wrappedCachedValue.Entity && navigation.Equals((object)this.RelationshipNavigation)) { this.Remove(this._wrappedCachedValue, false, false, false, false, false); } else { this.Remove(this._wrappedCachedValue, true, doCascadeDelete, false, true, false); } } else if (this.WrappedOwner.Entity != null && this.WrappedOwner.Context != null && !this.UsingNoTracking) { this.WrappedOwner.Context.ObjectStateManager.GetEntityEntry(this.WrappedOwner.Entity).DeleteRelationshipsThatReferenceKeys(this.RelationshipSet, this.ToEndMember); } if (this.WrappedOwner.Entity == null) { return; } this.DetachedEntityKey = (EntityKey)null; }
internal override void VerifyType(IEntityWrapper wrappedEntity) { if (!this.CanSetEntityType(wrappedEntity)) { throw new InvalidOperationException(Strings.RelatedEnd_InvalidContainedType_Reference((object)wrappedEntity.Entity.GetType().FullName, (object)typeof(TEntity).FullName)); } }
private void CheckClearedEntryOnSpan( object targetValue, IEntityWrapper wrappedSource, EntityKey sourceKey, AssociationEndMember targetMember) { // If a relationship does not exist on the server but does exist on the client, // we may need to remove it, depending on the current state and the MergeOption if ((null != (object)sourceKey) && (null == targetValue) && (MergeOption == MergeOption.PreserveChanges || MergeOption == MergeOption.OverwriteChanges)) { // When the spanned value is null, it may be because the spanned association applies to a // subtype of the entity's type, and the entity is not actually an instance of that type. var sourceEnd = MetadataHelper.GetOtherAssociationEnd(targetMember); EdmType expectedSourceType = ((RefType)sourceEnd.TypeUsage.EdmType).ElementType; TypeUsage entityTypeUsage; if (!Context.Perspective.TryGetType(wrappedSource.IdentityType, out entityTypeUsage) || entityTypeUsage.EdmType.EdmEquals(expectedSourceType) || TypeSemantics.IsSubTypeOf(entityTypeUsage.EdmType, expectedSourceType)) { // Otherwise, the source entity is the correct type (exactly or a subtype) for the source // end of the spanned association, so validate that the relationhip that was spanned is // part of the Container owning the EntitySet of the root entity. // This can be done by comparing the EntitySet of the row's entity to the relationships // in the Container and their AssociationSetEnd's type CheckClearedEntryOnSpan(sourceKey, targetMember); } } }
private void IncludeEntityKey(bool doAttach) { ObjectStateManager objectStateManager = this.ObjectContext.ObjectStateManager; bool flag1 = false; bool flag2 = false; EntityEntry entityEntry = objectStateManager.FindEntityEntry(this.DetachedEntityKey); if (entityEntry == null) { flag2 = true; flag1 = true; } else if (entityEntry.IsKeyEntry) { if (this.FromEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many) { foreach (RelationshipEntry relationshipEntry in this.ObjectContext.ObjectStateManager.FindRelationshipsByKey(this.DetachedEntityKey)) { if (relationshipEntry.IsSameAssociationSetAndRole((AssociationSet)this.RelationshipSet, (AssociationEndMember)this.ToEndMember, this.DetachedEntityKey) && relationshipEntry.State != EntityState.Deleted) { throw new InvalidOperationException(Strings.ObjectStateManager_EntityConflictsWithKeyEntry); } } } flag1 = true; } else { IEntityWrapper wrappedEntity = entityEntry.WrappedEntity; if (entityEntry.State == EntityState.Deleted) { throw new InvalidOperationException(Strings.RelatedEnd_UnableToAddRelationshipWithDeletedEntity); } RelatedEnd relatedEndInternal = wrappedEntity.RelationshipManager.GetRelatedEndInternal(this.RelationshipName, this.RelationshipNavigation.From); if (this.FromEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many && !relatedEndInternal.IsEmpty()) { throw new InvalidOperationException(Strings.ObjectStateManager_EntityConflictsWithKeyEntry); } this.Add(wrappedEntity, true, doAttach, false, true, true); objectStateManager.TransactionManager.PopulatedEntityReferences.Add((EntityReference)this); } if (!flag1 || this.IsForeignKey) { return; } if (flag2) { EntitySet entitySet = this.DetachedEntityKey.GetEntitySet(this.ObjectContext.MetadataWorkspace); objectStateManager.AddKeyEntry(this.DetachedEntityKey, entitySet); } EntityKey entityKey = this.WrappedOwner.EntityKey; if ((object)entityKey == null) { throw Error.EntityKey_UnexpectedNull(); } RelationshipWrapper wrapper = new RelationshipWrapper((AssociationSet)this.RelationshipSet, this.RelationshipNavigation.From, entityKey, this.RelationshipNavigation.To, this.DetachedEntityKey); objectStateManager.AddNewRelation(wrapper, doAttach ? EntityState.Unchanged : EntityState.Added); }
// <summary> // Call to ensure a single full-spanned element is added into // the state manager properly. // </summary> public IEntityWrapper HandleFullSpanElement( IEntityWrapper wrappedSource, IEntityWrapper wrappedSpannedEntity, AssociationEndMember targetMember) { DebugCheck.NotNull(wrappedSource); if (wrappedSource.Entity == null) { return(wrappedSource); } List <IEntityWrapper> spannedEntities = null; if (wrappedSpannedEntity.Entity != null) { // There was a single entity in the column // Create a list so we can perform the same logic as a collection of entities spannedEntities = new List <IEntityWrapper>(1); spannedEntities.Add(wrappedSpannedEntity); } else { var sourceKey = wrappedSource.EntityKey; CheckClearedEntryOnSpan(null, wrappedSource, sourceKey, targetMember); } FullSpanAction(wrappedSource, spannedEntities, targetMember); return(wrappedSource); }
protected void RegisterMaterializedEntityForEvent(IEntityWrapper wrappedEntity) { if (_materializedEntities != null) { _materializedEntities.Add(wrappedEntity); } }
internal override bool CheckIfNavigationPropertyContainsEntity(IEntityWrapper wrapper) { Debug.Assert(this.RelationshipNavigation != null, "null RelationshipNavigation"); // If the navigation property doesn't exist (e.g. unidirectional prop), then it can't contain the entity. if (!TargetAccessor.HasProperty) { return(false); } object value = this.WrappedOwner.GetNavigationPropertyValue(this); if (value != null) { if (!(value is IEnumerable)) { throw new EntityException(System.Data.Entity.Strings.ObjectStateEntry_UnableToEnumerateCollection( this.TargetAccessor.PropertyName, this.WrappedOwner.Entity.GetType().FullName)); } // foreach (object o in (value as IEnumerable)) { if (Object.Equals(o, wrapper.Entity)) { return(true); } } } return(false); }
internal override bool CheckIfNavigationPropertyContainsEntity(IEntityWrapper wrapper) { if (!this.TargetAccessor.HasProperty) { return(false); } bool state = this.DisableLazyLoading(); try { object navigationPropertyValue = this.WrappedOwner.GetNavigationPropertyValue((RelatedEnd)this); if (navigationPropertyValue != null) { IEnumerable <TEntity> source = navigationPropertyValue as IEnumerable <TEntity>; if (source == null) { throw new EntityException(Strings.ObjectStateEntry_UnableToEnumerateCollection((object)this.TargetAccessor.PropertyName, (object)this.WrappedOwner.Entity.GetType().FullName)); } HashSet <TEntity> entitySet = navigationPropertyValue as HashSet <TEntity>; if (!wrapper.OverridesEqualsOrGetHashCode || entitySet != null && entitySet.Comparer is ObjectReferenceEqualityComparer) { return(source.Contains <TEntity>((TEntity)wrapper.Entity)); } return(source.Any <TEntity>((Func <TEntity, bool>)(o => object.ReferenceEquals((object)o, wrapper.Entity)))); } } finally { this.ResetLazyLoading(state); } return(false); }
internal override bool CheckIfNavigationPropertyContainsEntity(IEntityWrapper wrapper) { if (!this.TargetAccessor.HasProperty) { return(false); } return(object.ReferenceEquals(this.WrappedOwner.GetNavigationPropertyValue((RelatedEnd)this), wrapper.Entity)); }
internal override bool ContainsEntity(IEntityWrapper wrappedEntity) { if (this._wrappedCachedValue.Entity != null) { return(this._wrappedCachedValue.Entity == wrappedEntity.Entity); } return(false); }
internal override bool RemoveFromObjectCache(IEntityWrapper wrappedEntity) { if (this.TargetAccessor.HasProperty) { this.WrappedOwner.RemoveNavigationPropertyValue((RelatedEnd)this, wrappedEntity.Entity); } return(true); }
internal override void AddToObjectCache(IEntityWrapper wrappedEntity) { if (!this.TargetAccessor.HasProperty) { return; } this.WrappedOwner.SetNavigationPropertyValue((RelatedEnd)this, wrappedEntity.Entity); }
internal override void AddToObjectCache(IEntityWrapper wrappedEntity) { // For POCO entities - set the CLR reference if (this.TargetAccessor.HasProperty) { this.WrappedOwner.SetNavigationPropertyValue(this, wrappedEntity.Entity); } }
internal EntityReference( IEntityWrapper wrappedOwner, RelationshipNavigation navigation, IRelationshipFixer relationshipFixer) : base(wrappedOwner, navigation, relationshipFixer) { this._wrappedCachedValue = NullEntityWrapper.NullWrapper; }
public GetHelper(IEntityWrapper entityWrapper) { _entityWrapper = entityWrapper; }
public void SetUp() { _entityWrapper = Substitute.For<IEntityWrapper>(); _postHelper = new PostHelper(_entityWrapper); }
/// <summary> /// Set the proxy object's private entity wrapper field value to the specified entity wrapper object. /// The proxy object (representing the wrapped entity) is retrieved from the wrapper itself. /// </summary> /// <param name="wrapper">Wrapper object to be referenced by the proxy.</param> /// <returns> /// The supplied entity wrapper. /// This is done so that this method can be more easily composed within lambda expressions (such as in the materializer). /// </returns> internal IEntityWrapper SetEntityWrapper(IEntityWrapper wrapper) { Debug.Assert(wrapper != null, "wrapper must be non-null"); Debug.Assert(wrapper.Entity != null, "proxy must be non-null"); return Proxy_SetEntityWrapper(wrapper.Entity, wrapper) as IEntityWrapper; }
private EntityKey ExtractPrincipalKey(IEntityWrapper wrappedRelatedEntity) { var principalEntitySet = GetTargetEntitySetFromRelationshipSet(); // get or create a key to use to compare the values -- the target entity might not have been attached // yet so it may not have a key, but we can create one here to use for checking the values var principalKey = wrappedRelatedEntity.EntityKey; if (null != (object)principalKey && !principalKey.IsTemporary) { // Validate the key here because we need to get values from it for verification // and that will fail if the key is malformed. // Verify only if the key already exists. EntityUtil.ValidateEntitySetInKey(principalKey, principalEntitySet); principalKey.ValidateEntityKey(ObjectContext.MetadataWorkspace, principalEntitySet); } else { principalKey = ObjectContext.ObjectStateManager.CreateEntityKey(principalEntitySet, wrappedRelatedEntity.Entity); } return principalKey; }
internal override void AddEntityToObjectStateManager(IEntityWrapper wrappedEntity, bool doAttach) { base.AddEntityToObjectStateManager(wrappedEntity, doAttach); // Now that we know we have a valid EntityKey for the target entity, verify that it matches the detached EntityKey, if there is one if (DetachedEntityKey != null) { var targetKey = wrappedEntity.EntityKey; if (DetachedEntityKey != targetKey) { throw new InvalidOperationException(Strings.EntityReference_EntityKeyValueMismatch); } } // else -- null just means the key isn't set, so the target entity key doesn't also have to be null }
/// <summary> /// Takes key values from the given principal key and transfers them to the foreign key properties /// of the dependant entry. This method requires a context, but does not require that either /// entity or key is in the context. This allows it to work in NoTracking cases where we have the context /// but we're not tracked by that context. /// </summary> /// <param name="dependentEntity">The entity into which foreign key values will be written</param> /// <param name="principalEntity">The key from which key values will be obtained</param> internal void UpdateForeignKeyValues(IEntityWrapper dependentEntity, EntityKey principalKey) { Debug.Assert(dependentEntity.Entity != null, "dependentEntity.Entity == null"); Debug.Assert(principalKey != null, "principalKey == null"); Debug.Assert(!principalKey.IsTemporary, "Cannot update from a temp key"); Debug.Assert(IsForeignKey, "cannot update foreign key values if the relationship is not a FK"); var constraint = ((AssociationType)RelationMetadata).ReferentialConstraints[0]; Debug.Assert(constraint != null, "null constraint"); var stateManager = ObjectContext.ObjectStateManager; stateManager.TransactionManager.BeginForeignKeyUpdate(this); try { var dependentEntitySet = ((AssociationSet)RelationshipSet).AssociationSetEnds[FromEndMember.Name].EntitySet; var dependentTypeMetadata = stateManager.GetOrAddStateManagerTypeMetadata(dependentEntity.IdentityType, dependentEntitySet); for (var i = 0; i < constraint.FromProperties.Count; i++) { var value = principalKey.FindValueByName(constraint.FromProperties[i].Name); var dependentOrdinal = dependentTypeMetadata.GetOrdinalforOLayerMemberName(constraint.ToProperties[i].Name); var currentValue = dependentTypeMetadata.Member(dependentOrdinal).GetValue(dependentEntity.Entity); if (!ByValueEqualityComparer.Default.Equals(currentValue, value)) { dependentEntity.SetCurrentValue( dependentEntity.ObjectStateEntry, dependentTypeMetadata.Member(dependentOrdinal), -1, dependentEntity.Entity, value); } } SetCachedForeignKey(principalKey, dependentEntity.ObjectStateEntry); if (WrappedOwner.ObjectStateEntry != null) { stateManager.ForgetEntryWithConceptualNull(WrappedOwner.ObjectStateEntry, resetAllKeys: false); } } finally { stateManager.TransactionManager.EndForeignKeyUpdate(); } }
internal static bool TryGetProxyWrapper(object instance, out IEntityWrapper wrapper) { Debug.Assert(instance != null, "the instance should not be null"); wrapper = null; EntityProxyTypeInfo proxyTypeInfo; if (IsProxyType(instance.GetType()) && TryGetProxyType(instance.GetType(), out proxyTypeInfo)) { wrapper = proxyTypeInfo.GetEntityWrapper(instance); } return wrapper != null; }
/// <summary> /// Takes key values from the given principal entity and transfers them to the foreign key properties /// of the dependant entry. This method requires a context, but does not require that either /// entity is in the context. This allows it to work in NoTracking cases where we have the context /// but we're not tracked by that context. /// </summary> /// <param name="dependentEntity">The entity into which foreign key values will be written</param> /// <param name="principalEntity">The entity from which key values will be obtained</param> /// <param name="changedFKs">If non-null, then keeps track of FKs that have already been set such that an exception can be thrown if we find conflicting values</param> /// <param name="forceChange">If true, then the property setter is called even if FK values already match, /// which causes the FK properties to be marked as modified.</param> internal void UpdateForeignKeyValues( IEntityWrapper dependentEntity, IEntityWrapper principalEntity, Dictionary<int, object> changedFKs, bool forceChange) { Debug.Assert(dependentEntity.Entity != null, "dependentEntity.Entity == null"); Debug.Assert(principalEntity.Entity != null, "principalEntity.Entity == null"); Debug.Assert(IsForeignKey, "cannot update foreign key values if the relationship is not a FK"); var constraint = ((AssociationType)RelationMetadata).ReferentialConstraints[0]; Debug.Assert(constraint != null, "null constraint"); var isUnchangedDependent = (object)WrappedOwner.EntityKey != null && !WrappedOwner.EntityKey.IsTemporary && IsDependentEndOfReferentialConstraint(checkIdentifying: true); var stateManager = ObjectContext.ObjectStateManager; stateManager.TransactionManager.BeginForeignKeyUpdate(this); try { var principalEntitySet = ((AssociationSet)RelationshipSet).AssociationSetEnds[ToEndMember.Name].EntitySet; var principalTypeMetadata = stateManager.GetOrAddStateManagerTypeMetadata(principalEntity.IdentityType, principalEntitySet); var dependentEntitySet = ((AssociationSet)RelationshipSet).AssociationSetEnds[FromEndMember.Name].EntitySet; var dependentTypeMetadata = stateManager.GetOrAddStateManagerTypeMetadata(dependentEntity.IdentityType, dependentEntitySet); var principalProps = constraint.FromProperties; var numValues = principalProps.Count; string[] keyNames = null; object[] values = null; if (numValues > 1) { keyNames = principalEntitySet.ElementType.KeyMemberNames; values = new object[numValues]; } for (var i = 0; i < numValues; i++) { var principalOrdinal = principalTypeMetadata.GetOrdinalforOLayerMemberName(principalProps[i].Name); var value = principalTypeMetadata.Member(principalOrdinal).GetValue(principalEntity.Entity); var dependentOrdinal = dependentTypeMetadata.GetOrdinalforOLayerMemberName(constraint.ToProperties[i].Name); var valueChanging = !ByValueEqualityComparer.Default.Equals( dependentTypeMetadata.Member(dependentOrdinal).GetValue(dependentEntity.Entity), value); if (forceChange || valueChanging) { if (isUnchangedDependent) { ValidateSettingRIConstraints( principalEntity, settingToNull: value == null, changingForeignKeyValue: valueChanging); } // If we're tracking FK values that have already been set, then compare the value we are about to set // to the value we previously set for this ordinal, if such a value exists. If they don't match then // it means that we got conflicting FK values from two different PKs and we should throw. if (changedFKs != null) { object previouslySetValue; if (changedFKs.TryGetValue(dependentOrdinal, out previouslySetValue)) { if (!ByValueEqualityComparer.Default.Equals(previouslySetValue, value)) { throw new InvalidOperationException(Strings.Update_ReferentialConstraintIntegrityViolation); } } else { changedFKs[dependentOrdinal] = value; } } dependentEntity.SetCurrentValue( dependentEntity.ObjectStateEntry, dependentTypeMetadata.Member(dependentOrdinal), -1, dependentEntity.Entity, value); } if (numValues > 1) { var keyIndex = Array.IndexOf(keyNames, principalProps[i].Name); Debug.Assert(keyIndex >= 0 && keyIndex < numValues, "Could not find constraint prop name in entity set key names"); values[keyIndex] = value; } else { SetCachedForeignKey(new EntityKey(principalEntitySet, value), dependentEntity.ObjectStateEntry); } } if (numValues > 1) { SetCachedForeignKey(new EntityKey(principalEntitySet, values), dependentEntity.ObjectStateEntry); } if (WrappedOwner.ObjectStateEntry != null) { stateManager.ForgetEntryWithConceptualNull(WrappedOwner.ObjectStateEntry, resetAllKeys: false); } } finally { stateManager.TransactionManager.EndForeignKeyUpdate(); } }
internal void ValidateSettingRIConstraints(IEntityWrapper targetEntity, bool settingToNull, bool changingForeignKeyValue) { var isNoTracking = targetEntity != null && targetEntity.MergeOption == MergeOption.NoTracking; if (settingToNull || // setting the principle to null changingForeignKeyValue || // existing key does not match incoming key (targetEntity != null && !isNoTracking && (targetEntity.ObjectStateEntry == null || // setting to a detached principle (EntityKey == null && targetEntity.ObjectStateEntry.State == EntityState.Deleted || // setting to a deleted principle (CachedForeignKey == null && targetEntity.ObjectStateEntry.State == EntityState.Added))))) // setting to an added principle { throw new InvalidOperationException(Strings.EntityReference_CannotChangeReferentialConstraintProperty); } }
internal EntityKey ValidateOwnerWithRIConstraints(IEntityWrapper targetEntity, EntityKey targetEntityKey, bool checkBothEnds) { var ownerKey = WrappedOwner.EntityKey; // Check if Referential Constraints are violated if ((object)ownerKey != null && !ownerKey.IsTemporary && IsDependentEndOfReferentialConstraint(checkIdentifying: true)) { Debug.Assert(CachedForeignKey != null || EntityKey == null, "CachedForeignKey should not be null if EntityKey is not null."); ValidateSettingRIConstraints( targetEntity, targetEntityKey == null, (CachedForeignKey != null && CachedForeignKey != targetEntityKey)); } else if (checkBothEnds && targetEntity != null && targetEntity.Entity != null) { var otherEnd = GetOtherEndOfRelationship(targetEntity) as EntityReference; if (otherEnd != null) { otherEnd.ValidateOwnerWithRIConstraints(WrappedOwner, ownerKey, checkBothEnds: false); } } return ownerKey; }
internal static IEnumerable<AssociationType> TryGetAllAssociationTypesFromProxyInfo(IEntityWrapper wrappedEntity) { DebugCheck.NotNull(wrappedEntity); EntityProxyTypeInfo proxyInfo; return TryGetProxyType(wrappedEntity.Entity.GetType(), out proxyInfo) ? proxyInfo.GetAllAssociationTypes() : null; }
/// <summary> /// A mechanism to lookup AssociationType metadata for proxies for a given entity and association information /// </summary> /// <param name="wrappedEntity"> The entity instance used to lookup the proxy type </param> /// <param name="relationshipName"> The name of the relationship (FullName or Name) </param> /// <param name="associationType"> The AssociationType for that property </param> /// <returns> True if an AssociationType is found in proxy metadata, false otherwise </returns> internal static bool TryGetAssociationTypeFromProxyInfo( IEntityWrapper wrappedEntity, string relationshipName, out AssociationType associationType) { DebugCheck.NotNull(wrappedEntity); DebugCheck.NotEmpty(relationshipName); EntityProxyTypeInfo proxyInfo; associationType = null; return (TryGetProxyType(wrappedEntity.Entity.GetType(), out proxyInfo) && proxyInfo != null && proxyInfo.TryGetNavigationPropertyAssociationType(relationshipName, out associationType)); }
internal static bool TryGetProxyWrapper(object instance, out IEntityWrapper wrapper) { DebugCheck.NotNull(instance); wrapper = null; EntityProxyTypeInfo proxyTypeInfo; if (IsProxyType(instance.GetType()) && TryGetProxyType(instance.GetType(), out proxyTypeInfo)) { wrapper = proxyTypeInfo.GetEntityWrapper(instance); } return wrapper != null; }
/// <summary> /// Set the proxy object's private entity wrapper field value to the specified entity wrapper object. /// The proxy object (representing the wrapped entity) is retrieved from the wrapper itself. /// </summary> /// <param name="wrapper"> Wrapper object to be referenced by the proxy. </param> /// <returns> The supplied entity wrapper. This is done so that this method can be more easily composed within lambda expressions (such as in the materializer). </returns> internal IEntityWrapper SetEntityWrapper(IEntityWrapper wrapper) { DebugCheck.NotNull(wrapper); DebugCheck.NotNull(wrapper.Entity); return Proxy_SetEntityWrapper(wrapper.Entity, wrapper) as IEntityWrapper; }
internal EntityReference(IEntityWrapper wrappedOwner, RelationshipNavigation navigation, IRelationshipFixer relationshipFixer) : base(wrappedOwner, navigation, relationshipFixer) { }
/// <summary> /// A mechanism to lookup AssociationType metadata for proxies for a given entity and association information /// </summary> /// <param name="wrappedEntity">The entity instance used to lookup the proxy type</param> /// <param name="relationshipName">The name of the relationship (FullName or Name)</param> /// <param name="targetRoleName">Target role of the relationship</param> /// <param name="associationType">The AssociationType for that property</param> /// <returns>True if an AssociationType is found in proxy metadata, false otherwise</returns> internal static bool TryGetAssociationTypeFromProxyInfo(IEntityWrapper wrappedEntity, string relationshipName, string targetRoleName, out AssociationType associationType) { EntityProxyTypeInfo proxyInfo = null; associationType = null; return (EntityProxyFactory.TryGetProxyType(wrappedEntity.Entity.GetType(), out proxyInfo) && proxyInfo != null && proxyInfo.TryGetNavigationPropertyAssociationType(relationshipName, targetRoleName, out associationType)); }