diff --git a/src/EFCore.InMemory/Query/Internal/CustomShaperCompilingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/CustomShaperCompilingExpressionVisitor.cs index f3211900996..3e12627407d 100644 --- a/src/EFCore.InMemory/Query/Internal/CustomShaperCompilingExpressionVisitor.cs +++ b/src/EFCore.InMemory/Query/Internal/CustomShaperCompilingExpressionVisitor.cs @@ -45,7 +45,8 @@ private static void IncludeReference { if (entity is TIncludingEntity includingEntity) { - if (trackingQuery) + if (trackingQuery + && navigation.DeclaringEntityType.FindPrimaryKey() != null) { // For non-null relatedEntity StateManager will set the flag if (relatedEntity == null) diff --git a/src/EFCore.Relational/Query/IncludeCompilingExpressionVisitor.cs b/src/EFCore.Relational/Query/IncludeCompilingExpressionVisitor.cs index 2a1c6ec676c..24cd4a731ef 100644 --- a/src/EFCore.Relational/Query/IncludeCompilingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/IncludeCompilingExpressionVisitor.cs @@ -48,7 +48,8 @@ private static void IncludeReference { if (entity is TIncludingEntity includingEntity) { - if (trackingQuery) + if (trackingQuery + && navigation.DeclaringEntityType.FindPrimaryKey() != null) { // For non-null relatedEntity StateManager will set the flag if (relatedEntity == null) diff --git a/src/EFCore/Internal/InternalDbSet.cs b/src/EFCore/Internal/InternalDbSet.cs index 81319fa190d..45d564dbe76 100644 --- a/src/EFCore/Internal/InternalDbSet.cs +++ b/src/EFCore/Internal/InternalDbSet.cs @@ -111,18 +111,7 @@ private EntityQueryable EntityQueryable } private EntityQueryable CreateEntityQueryable() - { - var queryable = new EntityQueryable(_context.GetDependencies().QueryProvider); - -#pragma warning disable 618 - if (_entityType.FindPrimaryKey() == null) -#pragma warning restore 618 - { - queryable = (EntityQueryable)queryable.AsNoTracking(); - } - - return queryable; - } + => new EntityQueryable(_context.GetDependencies().QueryProvider); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs index db2f43742aa..911e88ae7a8 100644 --- a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs +++ b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs @@ -40,7 +40,6 @@ protected ShapedQueryCompilingExpressionVisitor( QueryCompilationContext queryCompilationContext) { Dependencies = dependencies; - IsTracking = queryCompilationContext.IsTracking; _entityMaterializerInjectingExpressionVisitor = @@ -283,11 +282,6 @@ private Expression ProcessEntityShaper(EntityShaperExpression entityShaperExpres var primaryKey = entityType.FindPrimaryKey(); - if (_trackQueryResults && primaryKey == null) - { - throw new InvalidOperationException("A tracking query contains entityType without key in final result."); - } - var concreteEntityTypeVariable = Expression.Variable(typeof(IEntityType), "entityType" + _currentEntityIndex); variables.Add(concreteEntityTypeVariable); @@ -298,7 +292,8 @@ private Expression ProcessEntityShaper(EntityShaperExpression entityShaperExpres instanceVariable, Expression.Constant(null, entityType.ClrType))); - if (_trackQueryResults) + if (_trackQueryResults + && primaryKey != null) { var entryVariable = Expression.Variable(typeof(InternalEntityEntry), "entry" + _currentEntityIndex); var hasNullKeyVariable = Expression.Variable(typeof(bool), "hasNullKey" + _currentEntityIndex); @@ -439,7 +434,8 @@ var discriminatorValue expressions.Add(Expression.Assign(instanceVariable, materializationExpression)); - if (_trackQueryResults) + if (_trackQueryResults + && entityType.FindPrimaryKey() != null) { _visitedEntityTypes.Add(entityType); diff --git a/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs b/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs index 677bf26d4d8..65dbd728969 100644 --- a/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs +++ b/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs @@ -756,12 +756,15 @@ public virtual void Lazy_load_one_to_one_reference_to_dependent_not_found(Entity } [ConditionalTheory] + [InlineData(EntityState.Unchanged, CascadeTiming.OnSaveChanges)] + [InlineData(EntityState.Modified, CascadeTiming.OnSaveChanges)] + [InlineData(EntityState.Deleted, CascadeTiming.OnSaveChanges)] [InlineData(EntityState.Unchanged, CascadeTiming.Immediate)] [InlineData(EntityState.Modified, CascadeTiming.Immediate)] [InlineData(EntityState.Deleted, CascadeTiming.Immediate)] - [InlineData(EntityState.Unchanged, CascadeTiming.Immediate)] - [InlineData(EntityState.Modified, CascadeTiming.Immediate)] - [InlineData(EntityState.Deleted, CascadeTiming.Immediate)] + [InlineData(EntityState.Unchanged, CascadeTiming.Never)] + [InlineData(EntityState.Modified, CascadeTiming.Never)] + [InlineData(EntityState.Deleted, CascadeTiming.Never)] public virtual void Lazy_load_collection_already_loaded(EntityState state, CascadeTiming cascadeDeleteTiming) { using (var context = CreateContext(lazyLoadingEnabled: true)) diff --git a/test/EFCore.Specification.Tests/Query/InheritanceTestBase.cs b/test/EFCore.Specification.Tests/Query/InheritanceTestBase.cs index 06f3ef4139d..eb984f26486 100644 --- a/test/EFCore.Specification.Tests/Query/InheritanceTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/InheritanceTestBase.cs @@ -222,7 +222,7 @@ public virtual void Can_query_all_animal_views() { using (var context = CreateContext()) { - var animalQueries = context.Set().AsNoTracking().OrderBy(av => av.CountryId).ToList(); + var animalQueries = context.Set().OrderBy(av => av.CountryId).ToList(); Assert.Equal(2, animalQueries.Count); Assert.IsType(animalQueries[0]); diff --git a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.KeylessEntities.cs b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.KeylessEntities.cs index e45b5d052aa..887bd9a9c98 100644 --- a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.KeylessEntities.cs +++ b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.KeylessEntities.cs @@ -22,7 +22,7 @@ public virtual Task KeylessEntity_simple(bool isAsync) { return AssertQuery( isAsync, - cvs => cvs.AsNoTracking()); + cvs => cvs); } [ConditionalTheory] @@ -31,7 +31,7 @@ public virtual Task KeylessEntity_where_simple(bool isAsync) { return AssertQuery( isAsync, - cvs => cvs.AsNoTracking().Where(c => c.City == "London")); + cvs => cvs.Where(c => c.City == "London")); } [ConditionalFact] @@ -39,7 +39,7 @@ public virtual void KeylessEntity_by_database_view() { using (var context = CreateContext()) { - var results = context.Set().AsNoTracking().ToArray(); + var results = context.Set().ToArray(); Assert.Equal(69, results.Length); } @@ -50,7 +50,7 @@ public virtual void Auto_initialized_view_set() { using (var context = CreateContext()) { - var results = context.CustomerQueries.AsNoTracking().ToArray(); + var results = context.CustomerQueries.ToArray(); Assert.Equal(91, results.Length); } @@ -62,7 +62,7 @@ public virtual void KeylessEntity_with_nav_defining_query() using (var context = CreateContext()) { var results - = context.Set().AsNoTracking() + = context.Set() .Where(cq => cq.OrderCount > 0) .ToArray(); @@ -76,7 +76,7 @@ public virtual Task KeylessEntity_with_defining_query(bool isAsync) { return AssertQuery( isAsync, - ovs => ovs.AsNoTracking().Where(ov => ov.CustomerID == "ALFKI")); + ovs => ovs.Where(ov => ov.CustomerID == "ALFKI")); } // also issue 12873 @@ -86,7 +86,7 @@ public virtual Task KeylessEntity_with_defining_query_and_correlated_collection( { return AssertQuery( isAsync, - ovs => ovs.AsNoTracking().Where(ov => ov.CustomerID == "ALFKI").Select(ov => ov.Customer) + ovs => ovs.Where(ov => ov.CustomerID == "ALFKI").Select(ov => ov.Customer) .Select(cv => cv.Orders.Where(cc => true).ToList())); } @@ -98,7 +98,7 @@ public virtual Task KeylessEntity_with_mixed_tracking(bool isAsync) isAsync, (cs, ovs) => from c in cs - from o in ovs.AsNoTracking().Where(ov => ov.CustomerID == c.CustomerID) + from o in ovs.Where(ov => ov.CustomerID == c.CustomerID) select new { c, @@ -113,7 +113,7 @@ public virtual Task KeylessEntity_with_included_nav(bool isAsync) { return AssertIncludeQuery( isAsync, - ovs => from ov in ovs.AsNoTracking().Include(ov => ov.Customer) + ovs => from ov in ovs.Include(ov => ov.Customer) where ov.CustomerID == "ALFKI" select ov, new List @@ -128,7 +128,7 @@ public virtual Task KeylessEntity_with_included_navs_multi_level(bool isAsync) { return AssertIncludeQuery( isAsync, - ovs => from ov in ovs.AsNoTracking().Include(ov => ov.Customer.Orders) + ovs => from ov in ovs.Include(ov => ov.Customer.Orders) where ov.CustomerID == "ALFKI" select ov, new List @@ -144,7 +144,7 @@ public virtual Task KeylessEntity_select_where_navigation(bool isAsync) { return AssertQuery( isAsync, - ovs => from ov in ovs.AsNoTracking() + ovs => from ov in ovs where ov.Customer.City == "Seattle" select ov); } @@ -155,7 +155,7 @@ public virtual Task KeylessEntity_select_where_navigation_multi_level(bool isAsy { return AssertQuery( isAsync, - ovs => from ov in ovs.AsNoTracking() + ovs => from ov in ovs where ov.Customer.Orders.Any() select ov); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs index e4042717c6e..b70b96c36e1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs @@ -4874,8 +4874,6 @@ FROM [Orders] AS [o] WHERE (([c].[CustomerID] = [o].[CustomerID]) AND [o].[CustomerID] IS NOT NULL) AND (([c].[CustomerID] = [o].[CustomerID]) AND [o].[CustomerID] IS NOT NULL)) > 0"); } - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] public override async Task Convert_to_nullable_on_nullable_value_is_ignored(bool isAsync) { await base.Convert_to_nullable_on_nullable_value_is_ignored(isAsync);