Skip to content

Commit

Permalink
You can't fire me because I quit! (Change from Added to Deleted resul…
Browse files Browse the repository at this point in the history
…ts in detached entity)

See issue dotnet#351. When an entity is in the Added state it means that it doesn't exist in the database and should be inserted during SaveChanges. If the state is then changed to Deleted this would mean delete an entity that doesn't exist in the database, which will fail. In the EF6 stack we instead detach the entity in this case so that it is just never inserted. This change implements the same behavior in EF7.
  • Loading branch information
ajcvickers committed May 28, 2014
1 parent 1a376a0 commit 510f234
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/Microsoft.Data.Entity/ChangeTracking/StateEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,14 @@ private void SetEntityState(EntityState newState, Tuple<IProperty, object>[] gen
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;
}

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

_stateData.EntityState = newState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ public async Task Save_changes_removes_deleted_objects_from_store()

await inMemoryDataStore.SaveChangesAsync(new[] { entityEntry });

// Because the data store is being used directly the entity state must be manually changed after saving.
await entityEntry.SetEntityStateAsync(EntityState.Unchanged);

customer.Name = "Unikorn, The Return";
await entityEntry.SetEntityStateAsync(EntityState.Deleted);

Expand Down
19 changes: 19 additions & 0 deletions test/Microsoft.Data.Entity.Tests/ChangeTracking/StateEntryTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,25 @@ public void Changing_state_to_Unknown_causes_entity_to_stop_tracking()
Assert.DoesNotContain(entry, configuration.Services.StateManager.StateEntries);
}

[Fact] // GitHub #251
public void Changing_state_from_Added_to_Deleted_causes_entity_to_stop_tracking()
{
var model = BuildModel();
var entityType = model.GetEntityType("SomeEntity");
var keyProperty = entityType.GetProperty("Id");

var configuration = TestHelpers.CreateContextConfiguration(model);

var entry = CreateStateEntry(configuration, entityType, new SomeEntity());
entry[keyProperty] = 1;

entry.EntityState = EntityState.Added;
entry.EntityState = EntityState.Deleted;

Assert.Equal(EntityState.Unknown, entry.EntityState);
Assert.DoesNotContain(entry, configuration.Services.StateManager.StateEntries);
}

[Fact]
public void Changing_state_to_Modified_or_Unchanged_causes_all_properties_to_be_marked_accordingly()
{
Expand Down

0 comments on commit 510f234

Please sign in to comment.