/// <summary>
        ///     Throws an exception indicating that concurrency conflicts were detected.
        /// </summary>
        /// <param name="entry"> The update entry which resulted in the conflict(s). </param>
        /// <param name="concurrencyConflicts"> The conflicting properties with their associated database values. </param>
        protected virtual void ThrowUpdateConcurrencyException(
            [NotNull] IUpdateEntry entry, [NotNull] Dictionary <IProperty, object> concurrencyConflicts)
        {
            Check.NotNull(entry, nameof(entry));
            Check.NotNull(concurrencyConflicts, nameof(concurrencyConflicts));

            if (_sensitiveLoggingEnabled)
            {
                throw new DbUpdateConcurrencyException(
                          InMemoryStrings.UpdateConcurrencyTokenExceptionSensitive(
                              entry.EntityType.DisplayName(),
                              entry.BuildCurrentValuesString(entry.EntityType.FindPrimaryKey().Properties),
                              entry.BuildOriginalValuesString(concurrencyConflicts.Keys),
                              "{" + string.Join(
                                  ", ",
                                  concurrencyConflicts.Select(
                                      c => c.Key.Name + ": " + Convert.ToString(c.Value, CultureInfo.InvariantCulture)))
                              + "}"),
                          new[] { entry });
            }

            throw new DbUpdateConcurrencyException(
                      InMemoryStrings.UpdateConcurrencyTokenException(
                          entry.EntityType.DisplayName(),
                          concurrencyConflicts.Keys.Format()),
                      new[] { entry });
        }
Example #2
0
        /// <summary>
        ///     Adds an <see cref="IUpdateEntry" /> to this command representing an entity to be inserted, updated, or deleted.
        /// </summary>
        /// <param name="entry"> The entry representing the entity to add. </param>
        /// <param name="mainEntry"> A value indicating whether this is the main entry for the row. </param>
        public virtual void AddEntry([NotNull] IUpdateEntry entry, bool mainEntry)
        {
            Check.NotNull(entry, nameof(entry));

            switch (entry.EntityState)
            {
            case EntityState.Deleted:
            case EntityState.Modified:
            case EntityState.Added:
                break;

            default:
                if (_sensitiveLoggingEnabled)
                {
                    throw new InvalidOperationException(
                              RelationalStrings.ModificationCommandInvalidEntityStateSensitive(
                                  entry.EntityType.DisplayName(),
                                  entry.BuildCurrentValuesString(entry.EntityType.FindPrimaryKey().Properties),
                                  entry.EntityState));
                }

                throw new InvalidOperationException(
                          RelationalStrings.ModificationCommandInvalidEntityState(
                              entry.EntityType.DisplayName(),
                              entry.EntityState));
            }

            if (mainEntry)
            {
                Check.DebugAssert(!_mainEntryAdded, "Only expected a single main entry");

                for (var i = 0; i < _entries.Count; i++)
                {
                    ValidateState(entry, _entries[i]);
                }

                _mainEntryAdded = true;
                _entries.Insert(0, entry);
            }
            else
            {
                if (_mainEntryAdded)
                {
                    ValidateState(_entries[0], entry);
                }

                _entries.Add(entry);
            }

            _columnModifications = null;
        }
        /// <summary>
        ///     Adds an <see cref="IUpdateEntry" /> to this command representing an entity to be inserted, updated, or deleted.
        /// </summary>
        /// <param name="entry"> The entry representing the entity to add. </param>
        public virtual void AddEntry([NotNull] IUpdateEntry entry)
        {
            Check.NotNull(entry, nameof(entry));

            switch (entry.EntityState)
            {
            case EntityState.Deleted:
            case EntityState.Modified:
            case EntityState.Added:
                break;

            default:
                throw new ArgumentException(RelationalStrings.ModificationCommandInvalidEntityState(entry.EntityState));
            }

            if (_entries.Count > 0)
            {
                var lastEntry      = _entries[_entries.Count - 1];
                var lastEntryState = lastEntry.SharedIdentityEntry == null
                    ? lastEntry.EntityState
                    : EntityState.Modified;
                var entryState = entry.SharedIdentityEntry == null
                    ? entry.EntityState
                    : EntityState.Modified;
                if (lastEntryState != entryState)
                {
                    if (_sensitiveLoggingEnabled)
                    {
                        throw new InvalidOperationException(
                                  RelationalStrings.ConflictingRowUpdateTypesSensitive(
                                      entry.EntityType.DisplayName(),
                                      entry.BuildCurrentValuesString(entry.EntityType.FindPrimaryKey().Properties),
                                      entryState,
                                      lastEntry.EntityType.DisplayName(),
                                      lastEntry.BuildCurrentValuesString(lastEntry.EntityType.FindPrimaryKey().Properties),
                                      lastEntryState));
                    }

                    throw new InvalidOperationException(
                              RelationalStrings.ConflictingRowUpdateTypes(
                                  entry.EntityType.DisplayName(),
                                  entryState,
                                  lastEntry.EntityType.DisplayName(),
                                  lastEntryState));
                }
            }

            _entries.Add(entry);
            _columnModifications = null;
        }
Example #4
0
        private void ValidateState(IUpdateEntry mainEntry, IUpdateEntry entry)
        {
            var mainEntryState = mainEntry.SharedIdentityEntry == null
                ? mainEntry.EntityState
                : EntityState.Modified;

            if (mainEntryState == EntityState.Modified)
            {
                return;
            }

            var entryState = entry.SharedIdentityEntry == null
                ? entry.EntityState
                : EntityState.Modified;

            if (mainEntryState != entryState)
            {
                if (_sensitiveLoggingEnabled)
                {
                    throw new InvalidOperationException(
                              RelationalStrings.ConflictingRowUpdateTypesSensitive(
                                  entry.EntityType.DisplayName(),
                                  entry.BuildCurrentValuesString(entry.EntityType.FindPrimaryKey().Properties),
                                  entryState,
                                  mainEntry.EntityType.DisplayName(),
                                  mainEntry.BuildCurrentValuesString(mainEntry.EntityType.FindPrimaryKey().Properties),
                                  mainEntryState));
                }

                throw new InvalidOperationException(
                          RelationalStrings.ConflictingRowUpdateTypes(
                              entry.EntityType.DisplayName(),
                              entryState,
                              mainEntry.EntityType.DisplayName(),
                              mainEntryState));
            }
        }