/// <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 }); }
/// <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; }
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)); } }