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

Cosmos: Issues when loading derived type via base set and vice versa #25886

Open
roji opened this issue Sep 6, 2021 · 6 comments
Open

Cosmos: Issues when loading derived type via base set and vice versa #25886

roji opened this issue Sep 6, 2021 · 6 comments
Labels
area-cosmos area-query punted-for-7.0 Originally planned for the EF Core 7.0 (EF7) release, but moved out due to resource constraints. type-bug
Milestone

Comments

@roji
Copy link
Member

roji commented Sep 6, 2021

See FindCosmosTest.Find_base_type_using_derived_set_tracked (and async), Find_derived_using_base_set_type_from_store (and async).

@smitpatel
Copy link
Contributor

Can you share more details what is the issue?

@roji
Copy link
Member Author

roji commented Sep 6, 2021

Sure, I didn't dig into it, but as part of #25887 I enabled the FindTestBase suite for Cosmos, and the tests above failed - you can try checking out that PR and remove the skip, and you'll see right away.

@smitpatel
Copy link
Contributor

That is little friction. If you can post exception/error stack trace, generated SQL that would help us evaluate how difficult the fix is.

@roji
Copy link
Member Author

roji commented Sep 6, 2021

No problem. In Find_derived_using_base_set_type_from_store, Find returns nothing at all, whereas in Find_base_type_using_derived_set_tracked it would seem like we attempt to materialize and track the same instance twice.

Find_base_type_using_derived_set_tracked

System.InvalidOperationException: The instance of entity type 'DerivedType' cannot be tracked because another instance with the key value '{Id: 88}' i...

System.InvalidOperationException
The instance of entity type 'DerivedType' cannot be tracked because another instance with the key value '{Id: 88}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.ThrowIdentityConflict(InternalEntityEntry entry) in /home/roji/projects/efcore/src/EFCore/ChangeTracking/Internal/IdentityMap.cs:line 253
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry, Boolean updateDuplicate) in /home/roji/projects/efcore/src/EFCore/ChangeTracking/Internal/IdentityMap.cs:line 279
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry) in /home/roji/projects/efcore/src/EFCore/ChangeTracking/Internal/IdentityMap.cs:line 231
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(InternalEntityEntry entry) in /home/roji/projects/efcore/src/EFCore/ChangeTracking/Internal/IdentityMap.cs:line 213
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry) in /home/roji/projects/efcore/src/EFCore/ChangeTracking/Internal/StateManager.cs:line 566
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties) in /home/roji/projects/efcore/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs:line 323
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable`1 forceStateWhenUnknownKey) in /home/roji/projects/efcore/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs:line 165
   at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable`1.TryGenerateIdFromKeys(IProperty idProperty, Object& value) in /home/roji/projects/efcore/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs:line 163
   at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable`1.TryGetResourceId(String& resourceId) in /home/roji/projects/efcore/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs:line 114
   at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable`1.Enumerator.MoveNext() in /home/roji/projects/efcore/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs:line 219
   at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Boolean& found) in System.Linq.dll:token 0x60000f6+0x43
   at lambda_method391(Closure , QueryContext )
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query) in /home/roji/projects/efcore/src/EFCore/Query/Internal/QueryCompiler.cs:line 97
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression) in /home/roji/projects/efcore/src/EFCore/Query/Internal/EntityQueryProvider.cs:line 78
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate) in System.Linq.Queryable.dll:token 0x6000132+0x1c
   at Microsoft.EntityFrameworkCore.Internal.EntityFinder`1.Find(Object[] keyValues) in /home/roji/projects/efcore/src/EFCore/Internal/EntityFinder.cs:line 60
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Find(Object[] keyValues) in /home/roji/projects/efcore/src/EFCore/Internal/InternalDbSet.cs:line 176
   at Microsoft.EntityFrameworkCore.FindCosmosTest.FindCosmosTestSet.Find[TEntity](DbContext context, Object[] keyValues) in /home/roji/projects/efcore/test/EFCore.Cosmos.FunctionalTests/FindCosmosTest.cs:line 40
   at Microsoft.EntityFrameworkCore.FindTestBase`1.Find_base_type_using_derived_set_tracked() in /home/roji/projects/efcore/test/EFCore.Specification.Tests/FindTestBase.cs:line 182
Find_derived_using_base_set_type_from_store
System.NullReferenceException: Object reference not set to an instance of an object.

System.NullReferenceException
Object reference not set to an instance of an object.
   at Microsoft.EntityFrameworkCore.FindTestBase`1.Find_derived_using_base_set_type_from_store() in /home/roji/projects/efcore/test/EFCore.Specification.Tests/FindTestBase.cs:line 207

@ajcvickers
Copy link
Member

Investigated this. We have a DbSet<BaseType> and we execute the following query to find a DerivedType with the given key:

DbSet<BaseType>().Where(e => EF.Property<int>(e, "Id") == (int)ValueBuffer.get_Item(0))

For SQL Server with TPH, this translates to the following:

DECLARE @__p_0 int = 78;

SELECT [b].[Id], [b].[Discriminator], [b].[Foo], [b].[Boo]
FROM [BaseType] AS [b]
WHERE [b].[Id] = @__p_0

This finds and returns an instance of the DerivedType, as expected.

For Cosmos, the translation is:

-- @__p_0='78'
SELECT c
FROM root c
WHERE (c["Discriminator"] IN ("BaseType", "DerivedType") AND (c["Id"] = @__p_0))

This does not find the DerivedType instance; it returns no results.

@smitpatel
Copy link
Contributor

That SQL should find derived type instance. It has id value and discriminator for derived type is also included in Where.

@ajcvickers ajcvickers added this to the Backlog milestone Sep 11, 2021
@ajcvickers ajcvickers modified the milestones: Backlog, 7.0.0 Nov 10, 2021
@ajcvickers ajcvickers added punted-for-7.0 Originally planned for the EF Core 7.0 (EF7) release, but moved out due to resource constraints. and removed propose-punt labels Jul 7, 2022
@ajcvickers ajcvickers modified the milestones: 7.0.0, Backlog Jul 7, 2022
@smitpatel smitpatel removed their assignment Sep 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-cosmos area-query punted-for-7.0 Originally planned for the EF Core 7.0 (EF7) release, but moved out due to resource constraints. type-bug
Projects
None yet
Development

No branches or pull requests

3 participants