private bool PrepareForAdd(EntityState newState)
        {
            if (newState != EntityState.Added ||
                EntityState == EntityState.Added)
            {
                return(false);
            }

            // Temporarily change the internal state to unknown so that key generation, including setting key values
            // can happen without constraints on changing read-only values kicking in
            _stateData.EntityState = EntityState.Unknown;

            _stateData.FlagAllProperties(EntityType.Properties.Count(), isFlagged: false);

            return(true);
        }
Exemple #2
0
        private bool PrepareForAdd(EntityState newState)
        {
            if (newState != EntityState.Added ||
                EntityState == EntityState.Added)
            {
                return(false);
            }

            if (EntityState == EntityState.Modified)
            {
                _stateData.FlagAllProperties(EntityType.PropertyCount(), PropertyFlag.TemporaryOrModified, flagged: false);
            }

            // Temporarily change the internal state to unknown so that key generation, including setting key values
            // can happen without constraints on changing read-only values kicking in
            _stateData.EntityState = EntityState.Detached;

            StateManager.EndSingleQueryMode();

            return(true);
        }
Exemple #3
0
        private IEnumerable <Tuple <IProperty, IValueGenerator> > PrepareForAdd(EntityState newState)
        {
            if (newState != EntityState.Added ||
                EntityState == EntityState.Added)
            {
                return(null);
            }

            // Temporarily change the internal state to unknown so that key generation, including setting key values
            // can happen without constraints on changing read-only values kicking in
            _stateData.EntityState = EntityState.Unknown;

            _stateData.FlagAllProperties(_entityType.Properties.Count(), isFlagged: false);

            var generators = _entityType.Properties
                             .Where(p => (p.ValueGeneration == ValueGeneration.OnAdd || p.IsForeignKey()) && HasDefaultValue(p))
                             .Select(p => Tuple.Create(p, _configuration.ValueGeneratorCache.GetGenerator(p)))
                             .Where(g => g.Item2 != null)
                             .ToList();

            // Return null if there are no generators to avoid subsequent async method overhead
            return(generators.Count > 0 ? generators : null);
        }
        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);
        }