Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entity Framework gets slow in long Iteration Loops #27

Closed
hugodamiaodias opened this issue Aug 10, 2018 · 2 comments
Closed

Entity Framework gets slow in long Iteration Loops #27

hugodamiaodias opened this issue Aug 10, 2018 · 2 comments

Comments

@hugodamiaodias
Copy link

Hello,

With the current setup, if we do long insert iteration loops through the use of a repository, Entity Framework will get slower and slower creating real performance issues.

I believe this is due to the dbContext maintaining all past insertions in cache. Also, we cannot use something like:

using (EfRepository<T> repo = new EfRepository<T>) 
{
    .....
}

because the dbContext will be disposed and be unavailable to the repository on the next iteration.

Is there a way to configure StructureMap to allow us to use the above using clause (in the cases we deem it needed), with StructureMap providing a new instance of the dbContext? (Preferably maintaining the current behavior when we don't wish to use the using clause)

Thank you!
Damião Dias

@ardalis
Copy link
Owner

ardalis commented Aug 12, 2018

The default EF Core lifetime is Scoped, which has nothing to do with StructureMap (but StructureMap will use this if it's used as the container as in this case). If you want to create separately-scoped instances of DbContext, you can create child scopes as described here:

https://stackoverflow.com/questions/43722463/how-to-create-a-child-scope-from-the-parent-with-default-dependency-injection-in

You might at that point need to pass the dbContext into a new instance of a repo you create yourself, rather than requesting one from the container. Let me know if that helps/makes sense.

@ardalis ardalis closed this as completed Sep 27, 2018
@hugodamiaodias
Copy link
Author

Sorry it took me so long to get back to this.

I did not manage to solve the issue using your suggestion, but I'll leave here my workaround, in case it can be useful to someone else.

Basically I had a set of events that lead to a loop on 1000+ insertions, and as the dbContextkept everything in memory, it started to get slower and slower...

My solution was to detach all entities from the dbContext after each insertion, as they were not needed anymore.

...
// The event handler that dealt with the 1000+ similar events and thus generated 1000+ inserts
public void HandlePost(MyEntityCreatedEventPost domainEvent)
{
    ...
    _aggregate.Insert(entity);  // note: does a dbContext.SaveChanges()
    _aggregate.DetachAll();
    ...
}

// And the cleanup method to keep the dbContext nimble
public void DetachAll()
{
    foreach (EntityEntry dbEntityEntry in _dbContext.ChangeTracker.Entries().Where(e => e.Entity != null).ToList())
    {
        dbEntityEntry.State = EntityState.Detached;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants