MongoFramework icon indicating copy to clipboard operation
MongoFramework copied to clipboard

Problem on RemoveById(..)

Open GitMeLyK opened this issue 2 years ago • 2 comments

Hi, I have a question about the .RemoveById (...) method, at the moment that I execute it in a context with a collection Tenant does not set the deletion of the entity in the Tracking, and I do not understand if it is a behavior some wanted for reason or is it an error, looking on the command code against the .Remove (..) method you do a ModelToDelete but don't mark it as deleted. In Tracking even if I see the element with the status = EntityEntryState.NoChanges, at the moment of context.SaveChanges () on the DB the record is actually deleted, and in Tracking I keep seeing it, while doing the same operation with the .Remove ( ..) I see a different behavior. Here is a part of the test I was doing to better explain what I was trying to do.

                EntityTenantDummy NewItem = context.DbSetTenantEntities.Create();
                NewItem.Name = "EntityDummy.1";

                EntityTenantDummy NewItem2 = new EntityTenantDummy() { Name = "EntityDummy.Some" };
                context.DbSetTenantEntities.Add(NewItem2);

                EntityTenantDummy NewItem3 = new EntityTenantDummy() { Name = "EntityDummy.Some" };
                context.DbSetTenantEntities.Add(NewItem3);

                context.SaveChanges();

                Assert.IsTrue(NewItem.Id != null);
                Assert.IsTrue(NewItem2.Id != null);
                Assert.IsTrue(NewItem3.Id != null);

                NewItem3.Name = "EntityDummy.3.Renamed";
                context.SaveChanges();

                NewItem3.Name = "EntityDummy.3.Renamed.ToDelete";
                context.DbSetTenantEntities.Remove(NewItem3);

                // For Remove State is Valid "Deleted"
                Assert.AreEqual(EntityEntryState.Deleted, context.ChangeTracker.GetEntry(NewItem3).State);
                Assert.AreEqual(context.ChangeTracker.GetEntry(NewItem3).OriginalValues[3].ToString(), "EntityDummy.3.Renamed");
                context.SaveChanges();

                NewItem2.Description = "EntityDummy.Some.2.Updated";
                context.DbSetTenantEntities.Update(NewItem2);
                context.SaveChanges();

                context.DbSetTenantEntities.RemoveById(NewItem2.Id);
                // ???For RemoveById State not changed and is Valid "NoChanges"???
                Assert.AreEqual(EntityEntryState.NoChanges, context.ChangeTracker.GetEntry(NewItem2).State);
                context.SaveChanges();

Looking from the code, it seems to me that the RemoveEntityRange (..) method also has the same behavior.

Thanks in advance for your interest

GitMeLyK avatar Oct 21 '21 16:10 GitMeLyK

Hey @GitMeLyK - thanks for raising the issue!

The reason you don't see it in the change tracker is that RemoveRange(Expression<Func<TEntity, bool>> predicate) and RemoveById(object entityId) perform operations via "commands" than "entities". The reason for this is that either of these can be called without any entities in the change tracker.

That said, I never thought about what happens when you query an entity beforehand and then call those methods. I guess I assumed that if you want to remove an entity that you've already got, you'd call Remove(TEntity entity).

But you're right, the behaviour isn't right. I'm thinking what needs to happen is that after certain commands have run, they need to apply any changes to the change tracker too. Doing this "clean up" action after would still mean calling RemoveById(object entityId) wouldn't update the change tracker until SaveChanges is called but it would result in eventual consistency.

Turnerj avatar Oct 22 '21 00:10 Turnerj

Thank you very much for the quite comprehensive answer.

GitMeLyK avatar Oct 22 '21 14:10 GitMeLyK