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

Exception when using FromSql on entity with ComplexProperty #32699

Closed
kimbirkelund opened this issue Jan 2, 2024 · 3 comments · Fixed by #32867
Closed

Exception when using FromSql on entity with ComplexProperty #32699

kimbirkelund opened this issue Jan 2, 2024 · 3 comments · Fixed by #32867
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported Servicing-approved type-bug
Milestone

Comments

@kimbirkelund
Copy link

Reproduction: EfComplexPropertyFromSqlTests.zip

Given an entity like the following:

public class Entity
{
    public required ComplexPropertyType ComplexProperty { get; set; }

    public Guid Id { get; set; } = Guid.NewGuid();
}

[ComplexType]
public record ComplexPropertyType(
    string Property1,
    string Property2);

Which works fine when inserting and querying normally.

The problem occurs when trying to execute a FromSql query like so:

db.Entities.FromSql($"""SELECT * FROM Entities""").ToList();

Or similar (see the DoThis service in the attached code).

The following exception is thrown when running the attached code:

System.Collections.Generic.KeyNotFoundException: The given key 'Table: Entities  Key: PK_Entities {'Id'} PrimaryKey' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.GenerateComplexPropertyShaperExpression(StructuralTypeProjectionExpression containerProjection, IComplexProperty complexProperty)
   at Microsoft.EntityFrameworkCore.Query.StructuralTypeProjectionExpression.BindComplexProperty(IComplexProperty complexProperty)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.BindComplexProperty(StructuralTypeReferenceExpression typeReference, IComplexProperty complexProperty)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TryBindMember(Expression source, MemberIdentity member, Expression& expression, IPropertyBase& property)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TryBindMember(Expression source, MemberIdentity member, Expression& expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMember(MemberExpression memberExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression, Boolean applyDefaultTypeMapping)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateProjection(Expression expression, Boolean applyDefaultTypeMapping)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitNew(NewExpression newExpression)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression, Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at EfComplexPropertyFromSqlTests.DoThis.Log[T](String name, IQueryable`1 queryable) in C:\Users\kim\source\tests\EfComplexPropertyFromSqlTests\EfComplexPropertyFromSqlTests\DoThis.cs:line 49
   at EfComplexPropertyFromSqlTests.DoThis.ExecuteAsync(CancellationToken stoppingToken) in C:\Users\kim\source\tests\EfComplexPropertyFromSqlTests\EfComplexPropertyFromSqlTests\DoThis.cs:line 40
   at Microsoft.Extensions.Hosting.Internal.Host.TryExecuteBackgroundServiceAsync(BackgroundService backgroundService)

Provider and version information

EF Core version: 8
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0.100
Operating system: Windows 11

@ajcvickers ajcvickers self-assigned this Jan 10, 2024
@ajcvickers ajcvickers added this to the 8.0.x milestone Jan 11, 2024
ajcvickers added a commit that referenced this issue Jan 14, 2024
The difference between the DbSet queries (work) and the FromSql queries (don't work) is that the DbSet queries use the table mappings, while the FromSql queries use the default mappings. The default mappings don't contain complex types. This may be an issue in of itself.

Fixes #32699
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Jan 14, 2024
ajcvickers added a commit that referenced this issue Jan 19, 2024
Replaces #32816
Fixes #32699

As discussed, leaving FromSql to use the default mappings, but add complex types to the default mappings.
ajcvickers added a commit that referenced this issue Jan 23, 2024
Replaces #32816
Fixes #32699

As discussed, leaving FromSql to use the default mappings, but add complex types to the default mappings.
ajcvickers added a commit that referenced this issue Jan 23, 2024
* Add complex type mappings to the default relational mappings

Replaces #32816
Fixes #32699

As discussed, leaving FromSql to use the default mappings, but add complex types to the default mappings.

* Add note to SelectExpression
@ajcvickers ajcvickers reopened this Jan 23, 2024
ajcvickers added a commit that referenced this issue Jan 23, 2024
* Add complex type mappings to the default relational mappings

Replaces #32816
Fixes #32699

As discussed, leaving FromSql to use the default mappings, but add complex types to the default mappings.

* Add note to SelectExpression
ajcvickers added a commit that referenced this issue Jan 23, 2024
* Add complex type mappings to the default relational mappings

Replaces #32816
Fixes #32699

As discussed, leaving FromSql to use the default mappings, but add complex types to the default mappings.

* Add note to SelectExpression
@ajcvickers ajcvickers modified the milestones: 8.0.x, 8.0.3 Feb 2, 2024
@samisq
Copy link

samisq commented Feb 20, 2024

I encountered the exact same exception when using FromExpression that maps to a table-Valued function, instead of FromSql, like:

pubic class MyDbContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDbFunction(() => GetEntityWithCalcuationsFunc(Guid.Empty));
    }

    public IQueryable<Entity> GetEntityWithCalcuationsFunc(Guid id)
            => FromExpression(() => GetEntityWithCalcuationsFunc(id));
}

public class Entity
{
    public required ComplexPropertyType ComplexProperty { get; set; }

    public Guid Id { get; set; }
}

[ComplexType]
public record ComplexPropertyType(string Property1, string Property2);

Will this fix address it too?

@ajcvickers ajcvickers removed their assignment Aug 31, 2024
@AlexTankSWO
Copy link

AlexTankSWO commented Sep 11, 2024

I am facing the same issue. As soon as I remove my complex type property from my entity, FromSql works as expected.
We are using EF Core 8.0.1

But I could see that in 8.0.8 this issue does not occur anymore.

@AndriySvyryd
Copy link
Member

@samisq No, that's tracked in #34627

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported Servicing-approved type-bug
Projects
None yet
6 participants