Skip to content

Commit

Permalink
Always do tracking query for Load
Browse files Browse the repository at this point in the history
Issue: If the ChangeTracking behaviour is set to NoTracking then calling Load on tracked entity won't track resuls of load query. Which results in load failing.
The fix is to issue AsTracking query so that results from load query are added to state manager and will be fixed up with tracked query

Currently calling Load on non tracked query does not work so this fix is safe in that regard.

Resolves #12209
  • Loading branch information
smitpatel committed Jun 4, 2018
1 parent d2847f2 commit d4ef6da
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 1 deletion.
89 changes: 89 additions & 0 deletions src/EFCore.Specification.Tests/LoadTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,50 @@ public virtual async Task Load_collection(EntityState state, bool async)
}
}

[Theory]
[InlineData(EntityState.Unchanged, true)]
[InlineData(EntityState.Unchanged, false)]
[InlineData(EntityState.Modified, true)]
[InlineData(EntityState.Modified, false)]
[InlineData(EntityState.Deleted, true)]
[InlineData(EntityState.Deleted, false)]
public virtual async Task Load_collection_with_NoTracking_behavior(EntityState state, bool async)
{
using (var context = CreateContext())
{
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

var parent = context.Set<Parent>().Single();
ClearLog();
var collectionEntry = context.Entry(parent).Collection(e => e.Children);

context.Entry(parent).State = state;

Assert.False(collectionEntry.IsLoaded);

if (async)
{
await collectionEntry.LoadAsync();
}
else
{
collectionEntry.Load();
}

Assert.True(collectionEntry.IsLoaded);

RecordLog();
context.ChangeTracker.LazyLoadingEnabled = false;

Assert.Equal(2, parent.Children.Count());
Assert.All(parent.Children.Select(e => e.Parent), c => Assert.Same(parent, c));

Assert.Equal(3, context.ChangeTracker.Entries().Count());
}
}

[Theory]
[InlineData(EntityState.Unchanged, true)]
[InlineData(EntityState.Unchanged, false)]
Expand Down Expand Up @@ -1435,6 +1479,51 @@ public virtual async Task Load_one_to_one_reference_to_principal(EntityState sta
}
}
[Theory]
[InlineData(EntityState.Unchanged, true)]
[InlineData(EntityState.Unchanged, false)]
[InlineData(EntityState.Modified, true)]
[InlineData(EntityState.Modified, false)]
[InlineData(EntityState.Deleted, true)]
[InlineData(EntityState.Deleted, false)]
public virtual async Task Load_one_to_one_reference_to_principal_when_NoTracking_behavior(EntityState state, bool async)
{
using (var context = CreateContext())
{
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var single = context.Set<Single>().Single();
ClearLog();
var referenceEntry = context.Entry(single).Reference(e => e.Parent);

context.Entry(single).State = state;

Assert.False(referenceEntry.IsLoaded);

if (async)
{
await referenceEntry.LoadAsync();
}
else
{
referenceEntry.Load();
}

Assert.True(referenceEntry.IsLoaded);

RecordLog();

Assert.Equal(2, context.ChangeTracker.Entries().Count());

var parent = context.ChangeTracker.Entries<Parent>().Single().Entity;

Assert.Same(parent, single.Parent);
Assert.Same(single, parent.Single);
}
}

[Theory]
[InlineData(EntityState.Unchanged, true)]
[InlineData(EntityState.Unchanged, false)]
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/Internal/EntityFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ private IQueryable<object[]> GetDatabaseValuesQuery(InternalEntityEntry entry)
}

private IQueryable<TEntity> Query(INavigation navigation, object[] keyValues)
=> _queryRoot.Where(BuildLambda(GetLoadProperties(navigation), new ValueBuffer(keyValues)));
=> _queryRoot.Where(BuildLambda(GetLoadProperties(navigation), new ValueBuffer(keyValues))).AsTracking();

/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
Expand Down

0 comments on commit d4ef6da

Please sign in to comment.