Skip to content

Commit

Permalink
Fix issues with LocalView (#28960)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajcvickers authored Sep 2, 2022
1 parent eb49719 commit 6054bee
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/EFCore/ChangeTracking/Internal/StateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,11 @@ public virtual void Clear()
_needsUnsubscribe = false;

SavingChanges = false;

foreach (IResettableService set in ((IDbSetCache)Context).GetSets())
{
set.ResetState();
}
}

/// <summary>
Expand Down
4 changes: 3 additions & 1 deletion src/EFCore/ChangeTracking/LocalView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,9 @@ public virtual bool Contains(TEntity item)
{
var entry = _context.GetDependencies().StateManager.TryGetEntry(item);

return entry != null && entry.EntityState != EntityState.Deleted;
return entry != null
&& entry.EntityState != EntityState.Deleted
&& entry.EntityState != EntityState.Detached;
}

/// <summary>
Expand Down
10 changes: 10 additions & 0 deletions src/EFCore/DbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,16 @@ object IDbSetCache.GetOrAddSet(IDbSetSource source, string entityTypeName, Type
return set;
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
[EntityFrameworkInternal]
IEnumerable<object> IDbSetCache.GetSets()
=> _sets?.Values ?? Enumerable.Empty<object>();

/// <summary>
/// Creates a <see cref="DbSet{TEntity}" /> that can be used to query and save instances of <typeparamref name="TEntity" />.
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions src/EFCore/Internal/IDbSetCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,12 @@ public interface IDbSetCache
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
object GetOrAddSet(IDbSetSource source, string entityTypeName, Type type);

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
IEnumerable<object> GetSets();
}
20 changes: 19 additions & 1 deletion test/EFCore.Specification.Tests/DatabindingTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,31 @@ public virtual void Entities_with_state_changed_to_detached_are_removed_from_loc

Assert.Equal(TotalCount, local.Count);

foreach (var driver in context.Drivers.Local.Where(d => d.TeamId == UnchangedTeam).ToList())
var drivers = context.Drivers.Local.Where(d => d.TeamId == UnchangedTeam).ToList();

foreach (var driver in drivers)
{
context.Entry(driver).State = EntityState.Detached;
}

Assert.Equal(0, local.Count(d => d.TeamId == UnchangedTeam));
Assert.Equal(TotalCount - UnchangedCount, local.Count);
foreach (var driver in drivers)
{
Assert.False(local.Contains(driver));
}

foreach (var driver in drivers)
{
Assert.Equal(EntityState.Detached, context.Entry(driver).State);
}

Assert.Equal(0, local.Count(d => d.TeamId == UnchangedTeam));
Assert.Equal(TotalCount - UnchangedCount, local.Count);
foreach (var driver in drivers)
{
Assert.False(local.Contains(driver));
}
}

[ConditionalTheory]
Expand Down
13 changes: 13 additions & 0 deletions test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3536,6 +3536,19 @@ public void Shadow_properties_are_not_included_in_update_unless_value_explicitly
AssertValuesSaved(id, 0, null);
}

[ConditionalFact]
public void Clearing_change_tracker_resets_local_view_count()
{
using var context = new LikeAZooContext();

int originalCount = context.Cats.Local.Count;
context.Cats.Add(new Cat(3));

context.ChangeTracker.Clear();

Assert.Equal(originalCount, context.Cats.Local.Count);
}

private static void AssertValuesSaved(int id, int someInt, string? someString)
{
using var context = new TheShadows();
Expand Down

0 comments on commit 6054bee

Please sign in to comment.