コード例 #1
0
ファイル: StateEntry.cs プロジェクト: Elidiomar/ef_core
        private void SetEntityState(EntityState oldState, EntityState 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.Properties.Count(), isFlagged: true);

                foreach (var keyProperty in EntityType.Properties.Where(
                             p => p.IsReadOnly ||
                             p.ValueGeneration == ValueGeneration.OnAddAndUpdate))
                {
                    _stateData.FlagProperty(keyProperty.Index, isFlagged: false);
                }
            }

            if (oldState == newState)
            {
                return;
            }

            // An Added entity does not yet exist in the database. If it is then marked as deleted there is
            // nothing to delete because it was not yet inserted, so just make sure it doesn't get inserted.
            if (oldState == EntityState.Added &&
                newState == EntityState.Deleted)
            {
                newState = EntityState.Unknown;
            }

            if (newState == EntityState.Unchanged)
            {
                _stateData.FlagAllProperties(_entityType.Properties.Count(), isFlagged: false);
            }

            _configuration.Services.StateEntryNotifier.StateChanging(this, newState);

            _stateData.EntityState = newState;

            if (oldState == EntityState.Unknown)
            {
                _configuration.StateManager.StartTracking(this);
            }
            else if (newState == EntityState.Unknown)
            {
                if (oldState == EntityState.Added)
                {
                    foreach (var property in _entityType.Properties.Where(p => _stateData.IsPropertyFlagged(p.Index)))
                    {
                        this[property] = property.PropertyType.GetDefaultValue();
                    }
                }

                // TODO: Does changing to Unknown really mean stop tracking?
                // Issue #323
                _configuration.StateManager.StopTracking(this);
            }

            _configuration.Services.StateEntryNotifier.StateChanged(this, oldState);
        }
コード例 #2
0
        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.Index));
                if (hasTempValue != null)
                {
                    throw new InvalidOperationException(Strings.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)
            {
                foreach (var property in EntityType.GetProperties().Where(
                             p => !p.IsReadOnlyAfterSave))
                {
                    _stateData.FlagProperty(property.Index, isFlagged: true);
                }
            }

            if (oldState == newState)
            {
                return;
            }

            if (newState == EntityState.Unchanged)
            {
                _stateData.FlagAllProperties(EntityType.GetProperties().Count(), isFlagged: false);
            }

            StateManager.Notify.StateChanging(this, newState);

            if (newState == EntityState.Unchanged &&
                oldState == EntityState.Modified)
            {
                if (acceptChanges)
                {
                    SetOriginalValue();
                }
                else
                {
                    ResetToOriginalValue();
                }
            }
            _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.Index)))
                    {
                        this[property] = property.SentinelValue;
                    }
                }
                _stateData.FlagAllProperties(EntityType.GetProperties().Count(), isFlagged: false);

                StateManager.StopTracking(this);
            }

            StateManager.Notify.StateChanged(this, oldState);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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.Unknown)
            {
                var hasTempValue = EntityType.Properties.FirstOrDefault(p => _stateData.IsPropertyFlagged(p.Index));
                if (hasTempValue != null)
                {
                    throw new InvalidOperationException(Strings.TempValuePersists(hasTempValue.Name, EntityType.SimpleName, 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.Properties.Count(), isFlagged: true);

                foreach (var keyProperty in EntityType.Properties.Where(
                             p => p.IsReadOnly ||
                             p.IsStoreComputed))
                {
                    _stateData.FlagProperty(keyProperty.Index, isFlagged: false);
                }
            }

            if (oldState == newState)
            {
                return;
            }

            if (newState == EntityState.Unchanged)
            {
                _stateData.FlagAllProperties(EntityType.Properties.Count(), isFlagged: false);
            }

            StateManager.Notify.StateChanging(this, newState);

            if (!acceptChanges &&
                newState == EntityState.Unchanged &&
                oldState == EntityState.Modified)
            {
                ResetToOriginalValue();
            }
            _stateData.EntityState = newState;

            if (oldState == EntityState.Unknown)
            {
                StateManager.StartTracking(this);
            }
            else if (newState == EntityState.Unknown)
            {
                if (oldState == EntityState.Added)
                {
                    foreach (var property in EntityType.Properties.Where(p => _stateData.IsPropertyFlagged(p.Index)))
                    {
                        this[property] = property.PropertyType.GetDefaultValue();
                    }
                }
                _stateData.FlagAllProperties(EntityType.Properties.Count(), isFlagged: false);

                // TODO: Does changing to Unknown really mean stop tracking?
                // Issue #323
                StateManager.StopTracking(this);
            }

            StateManager.Notify.StateChanged(this, oldState);
        }
コード例 #5
0
        private void SetEntityState(EntityState newState, Tuple <IProperty, object>[] generatedValues)
        {
            // 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.Properties.Count(), isFlagged: true);

                // Assuming key properties are not modified
                foreach (var keyProperty in EntityType.GetPrimaryKey().Properties)
                {
                    _stateData.FlagProperty(keyProperty.Index, isFlagged: false);
                }
            }

            var oldState = _stateData.EntityState;

            if (oldState == newState)
            {
                return;
            }

            // An Added entity does not yet exist in the database. If it is then marked as deleted there is
            // nothing to delete because it was not yet inserted, so just make sure it doesn't get inserted.
            if (oldState == EntityState.Added &&
                newState == EntityState.Deleted)
            {
                newState = EntityState.Unknown;
            }

            if (newState == EntityState.Unchanged || newState == EntityState.Added)
            {
                _stateData.FlagAllProperties(_entityType.Properties.Count(), isFlagged: false);
            }

            _configuration.Services.StateEntryNotifier.StateChanging(this, newState);

            if (newState == EntityState.Added)
            {
                foreach (var generatedValue in generatedValues.Where(v => v != null && v.Item2 != null))
                {
                    this[generatedValue.Item1] = generatedValue.Item2;
                    // TODO: Set default flag or not based on strategy
                    _stateData.FlagProperty(generatedValue.Item1.Index, isFlagged: false);
                }
            }
            else
            {
                Contract.Assert(generatedValues == null);
            }

            _stateData.EntityState = newState;

            if (oldState == EntityState.Unknown)
            {
                _configuration.StateManager.StartTracking(this);
            }
            else if (newState == EntityState.Unknown)
            {
                // TODO: Does changing to Unknown really mean stop tracking?
                _configuration.StateManager.StopTracking(this);
            }

            _configuration.Services.StateEntryNotifier.StateChanged(this, oldState);
        }
コード例 #6
0
        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);
        }