SaveChanges takes a lot of time due to expensive looping in method MetadataHelper.GetAssociationsForEntitySet(EntitySetBase entitySetKey)
See original GitHub issueThis issue was discussed earlier in 2012 on MSDN forums but it didn’t go anywhere. We now have a genuine need to fix this problem as described here:
Entity Model:
Order - root entity OrderItem - 1-M child of Order
Order and OrderItem have a few FK associations with other master entities such as Customer and Product.
Scenario:
We are creating a new Order and many OrderItems (~600,000) within a single instance of DbContext and calling SaveChanges in the end.
We found that DbContext.SaveChanges was taking a lot of time, so we decided to run our application with dotTrace Profiler, which reported following method as a hot-spot taking almost 70% time:
System.Data.Common.Utils.MetadataHelper.GetAssociationsForEntitySet(EntitySetBase)
DBContext Settings:
- Configuration.AutoDetectChangesEnabled = false;
- Configuration.ValidateOnSaveEnabled = false;
Potential Solution: We made a small change to this method to avoid looping and use a dictionary instead to lookup for associations.
private static readonly ConcurrentDictionary<EntitySetBase, List<AssociationSet>> _associationSetsForEntitySet = new ConcurrentDictionary<EntitySetBase, List<AssociationSet>>();
Then fixed the method to use the dictionary as follows:
// requires: entitySet
// effects: Returns the associations that occur between entitySet
// and other entitySets. If none is found, returns an empty set
internal static List<AssociationSet> GetAssociationsForEntitySet(EntitySetBase entitySetKey)
{
DebugCheck.NotNull(entitySetKey);
return _associationSetsForEntitySet.GetOrAdd(
entitySetKey, entitySet =>
{
var result = new List<AssociationSet>();
foreach (var extent in entitySet.EntityContainer.BaseEntitySets)
{
if (Helper.IsRelationshipSet(extent))
{
var assocSet = (AssociationSet)extent;
if (IsExtentAtSomeRelationshipEnd(assocSet, entitySet))
{
result.Add(assocSet);
}
}
}
return result;
});
}
The performance indeed improved significantly as seen in the attached profiler snapshots:
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:5 (2 by maintainers)
@ajcvickers I will submit a pull request soon. Thanks for your comment.
@ravi-pathak Thanks for finding that. We plan to release EF6.2 soon–we have been having some infrastructure issues that has delayed a number of things, but as of the end of last week we seem to be past them, so we’re going to try to get this out soon now.