private void SetEntityState(EntityState oldState, EntityState newState, bool acceptChanges) { // Prevent temp values from becoming permanent values if (oldState == EntityState.Added && newState != EntityState.Added && newState != EntityState.Detached) { // ReSharper disable once LoopCanBeConvertedToQuery foreach (var property in EntityType.GetProperties()) { if (HasTemporaryValue(property)) { throw new InvalidOperationException(CoreStrings.TempValuePersists(property.Name, EntityType.DisplayName(), newState)); } } } // The entity state can be Modified even if some properties are not modified so always // set all properties to modified if the entity state is explicitly set to Modified. if (newState == EntityState.Modified) { _stateData.FlagAllProperties(EntityType.PropertyCount(), PropertyFlag.TemporaryOrModified, flagged: true); // Hot path; do not use LINQ foreach (var property in EntityType.GetProperties()) { if (property.IsReadOnlyAfterSave) { _stateData.FlagProperty(property.GetIndex(), PropertyFlag.TemporaryOrModified, isFlagged: false); } } StateManager.EndSingleQueryMode(); } if (oldState == newState) { return; } if (newState == EntityState.Unchanged) { _stateData.FlagAllProperties(EntityType.PropertyCount(), PropertyFlag.TemporaryOrModified, flagged: false); } StateManager.Notify.StateChanging(this, newState); if (newState == EntityState.Unchanged && oldState == EntityState.Modified) { if (acceptChanges) { _originalValues.AcceptChanges(this); } else { _originalValues.RejectChanges(this); } } _stateData.EntityState = newState; if (oldState == EntityState.Detached) { StateManager.StartTracking(this); } else if (newState == EntityState.Detached) { if (oldState == EntityState.Added) { foreach (var property in EntityType.GetProperties() .Where(p => { var propertyIndex = p.GetIndex(); return(_stateData.IsPropertyFlagged(propertyIndex, PropertyFlag.TemporaryOrModified) && !_stateData.IsPropertyFlagged(propertyIndex, PropertyFlag.Unknown)); })) { this[property] = property.ClrType.GetDefaultValue(); } } StateManager.StopTracking(this); } if ((newState == EntityState.Deleted || newState == EntityState.Detached) && HasConceptualNull) { _stateData.FlagAllProperties(EntityType.PropertyCount(), PropertyFlag.Null, flagged: false); } if (oldState == EntityState.Detached || oldState == EntityState.Unchanged) { if (newState == EntityState.Added || newState == EntityState.Deleted || newState == EntityState.Modified) { StateManager.ChangedCount++; } } else if (newState == EntityState.Detached || newState == EntityState.Unchanged) { StateManager.ChangedCount--; } StateManager.Notify.StateChanged(this, oldState, fromQuery: false); }
private void SetEntityState(EntityState oldState, EntityState newState, bool acceptChanges) { // Prevent temp values from becoming permanent values if ((oldState == EntityState.Added) && (newState != EntityState.Added) && (newState != EntityState.Detached)) { var hasTempValue = EntityType.GetProperties() .FirstOrDefault(p => _stateData.IsPropertyFlagged(p.GetIndex(), PropertyFlag.TemporaryOrModified)); if (hasTempValue != null) { throw new InvalidOperationException(CoreStrings.TempValuePersists(hasTempValue.Name, EntityType.DisplayName(), newState)); } } // The entity state can be Modified even if some properties are not modified so always // set all properties to modified if the entity state is explicitly set to Modified. if (newState == EntityState.Modified) { _stateData.FlagAllProperties(EntityType.PropertyCount(), PropertyFlag.TemporaryOrModified, flagged: true); // Hot path; do not use LINQ foreach (var property in EntityType.GetProperties()) { if (property.IsReadOnlyAfterSave) { _stateData.FlagProperty(property.GetIndex(), PropertyFlag.TemporaryOrModified, isFlagged: false); } } StateManager.SingleQueryMode = false; } if (oldState == newState) { return; } if (newState == EntityState.Unchanged) { _stateData.FlagAllProperties(EntityType.PropertyCount(), PropertyFlag.TemporaryOrModified, flagged: false); } StateManager.Notify.StateChanging(this, newState); if ((newState == EntityState.Unchanged) && (oldState == EntityState.Modified)) { if (acceptChanges) { _originalValues.AcceptChanges(this); } else { _originalValues.RejectChanges(this); } } _stateData.EntityState = newState; if (oldState == EntityState.Detached) { StateManager.StartTracking(this); } else if (newState == EntityState.Detached) { if (oldState == EntityState.Added) { foreach (var property in EntityType.GetProperties() .Where(p => _stateData.IsPropertyFlagged(p.GetIndex(), PropertyFlag.TemporaryOrModified))) { this[property] = property.ClrType.GetDefaultValue(); } } var propertyCount = EntityType.PropertyCount(); _stateData.FlagAllProperties(propertyCount, PropertyFlag.TemporaryOrModified, flagged: false); _stateData.FlagAllProperties(propertyCount, PropertyFlag.Null, flagged: false); StateManager.StopTracking(this); } StateManager.Notify.StateChanged(this, oldState, StateManager.SingleQueryMode == true); }