How to Clear Tracked Entities in Entity Framework

How do I clear tracked entities in entity framework

You can add a method to your DbContext or an extension method that uses the ChangeTracker to detach all the Added, Modified, and Deleted entities:

public void DetachAllEntities()
{
var changedEntriesCopy = this.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added ||
e.State == EntityState.Modified ||
e.State == EntityState.Deleted)
.ToList();

foreach (var entry in changedEntriesCopy)
entry.State = EntityState.Detached;
}

How to release tracked entities?

There are a variety of ways to do this, but I find this the most simple since you're trying to detach a specific entity.

_db.Entry(a).State = EntityState.Detached

As a plus it doesn't require changing any other code, including however you fetched the entity itself.

This one line makes it very clear of the intent. It also allows the following:

  1. Fetch an entity, or list of entities
  2. Do various types of work
  3. Detach an entity

I dislike the idea of changing existing queries on a DbContext when all I want to do is detach something.

How to clean-up an Entity Framework object context?

It was just a trivial bug but I am going to leave the question here - maybe it helps others.

I had the following

var objectStateEntries = this.objectContext
.ObjectStateManager
.GetObjectStateEntries(EntityState.Added);

foreach (var objectStateEntry in objectStateEntries)
{
this.objectContext.Detach(objectStateEntry);
}

while I wanted the following

foreach (var objectStateEntry in objectStateEntries)
{
this.objectContext.Detach(objectStateEntry.Entity);
}

and couldn't see it.

Is there a way to remove change tracking mechanism for a single entity?

I think you can use AsNoTracking and for Transactions use Detach

Youcontext.YourEntities.AsNoTracking().Where);

or use

Youcontext.Transactions.Detach(obj);

Entity is still being tracked although NoTracking behaviour is set

The problem was made difficult with the fact, that every time the entity moved down or up the layers (example: from uow to dbcontext and back, containing 2 mappings here alone).
This ensured that calling

dbContext.Entity(entity).State = EntityState.Detached;

was not an option, because Savechanges was called with the uow object, not dbContext. Also in the real use case the dbContext is out of reach, thus not being able to call functions from dbContext at all.

So I searched for options to detach all objects, that were still attached after saveChanges.

ChangeTracker.Clear(); 

satisfied this requirement.

The solution for this problem is:

 public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new())
{
var res = await base.SaveChangesAsync(cancellationToken);
ChangeTracker.Clear();
return res;
}

EF Core Remove by ID

The presented code is not enought for understanding the root cause.

If it is a web application you might have issue with sharing same database context accross all http requests. But db context should be uniq for each http request. Avoid to make it singleton.
If it is a console application - you might have an issue with a configuration.

Option 1:
Try to do this:

Context.Entry(entity).State = EntityState.Detached

This is not a solution, but just for troubleshooting.

Option 2:
Try to do a very simple Console application with your database context and run your first code snippet - it should work.

Can be usefull:

instance of entity type cannot be tracked because another instance with same key value is tracked



Related Topics



Leave a reply



Submit