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

Primitive collection - projection with owned entity #31420

Closed
alienwareone opened this issue Aug 7, 2023 · 4 comments
Closed

Primitive collection - projection with owned entity #31420

alienwareone opened this issue Aug 7, 2023 · 4 comments
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@alienwareone
Copy link

System.InvalidOperationException when projecting an entity with an owned entity to a new class.

Reproduction repository: https://github.com/alienwareone/EfCorePrimitiveCollectionProjection/blob/master/Program.cs

@ajcvickers
Copy link
Member

Exception message:

A tracking query is attempting to project an owned entity without a corresponding owner in its result, but owned entities cannot be tracked without their owner. Either include the owner entity in the result or make the query non-tracking using 'AsNoTracking'.

This is by-design. As the message says, use AsNoTracking.

@alienwareone
Copy link
Author

Thanks for your reply @ajcvickers

Strange. Tested several times and always get the following error (see code below). Removing the owned entity will work.

An exception of type 'System.InvalidOperationException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'Translation of 'EF.Property<int[]>(IncludeExpression(
    EntityExpression:
    EntityShaperExpression: 
        Category
        ValueBufferExpression: 
            ProjectionBindingExpression: EmptyProjectionMember
        IsNullable: False
    , 
    NavigationExpression:
    EntityShaperExpression: 
        Message
        ValueBufferExpression: 
            EntityProjectionExpression: Message
        IsNullable: True
    , Message)
, "Hierarchy")' failed. Either the query source is not an entity type, or the specified property does not exist on the entity type.'
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression, Boolean applyDefaultTypeMapping)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression, Boolean applyDefaultTypeMapping)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
   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.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>d__67`1.MoveNext()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.<ToArrayAsync>d__68`1.MoveNext()
   at Program.<<Main>$>d__0.MoveNext() in Program.cs:line 11
await using var dbContext = new ApplicationDbContext();
await dbContext.Database.EnsureDeletedAsync();
await dbContext.Database.EnsureCreatedAsync();

var result = await dbContext.Categories
  .AsNoTracking()
  .Select(x => new CategoryDto
  {
    Id = x.Id,
    Hierarchy = x.Hierarchy,
    Name = x.Name,
  })
  .ToArrayAsync();

public class ApplicationDbContext : DbContext
{
  public DbSet<Category> Categories { get; set; } = null!;

  protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder
      .UseSqlServer("Data Source = .\\SQLEXPRESS; Database = EfCorePrimitiveCollectionProjection; Integrated Security = True; TrustServerCertificate=True")
      .LogTo(Console.WriteLine, LogLevel.Debug)
      .EnableSensitiveDataLogging()
      .EnableDetailedErrors();

  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
    modelBuilder.Entity<Category>().OwnsOne(x => x.Message);
  }
}

public class Category
{
  public int Id { get; private set; }
  public required int[] Hierarchy { get; set; }
  public required string Name { get; set; }
  public Message? Message { get; set; }
}

public class Message
{
  public string? Text { get; set; }
}

public class CategoryDto
{
  public int Id { get; set; }
  public required int[] Hierarchy { get; set; }
  public required string Name { get; set; }
}
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <LangVersion>preview</LangVersion>
    <Nullable>enable</Nullable>
    <WarningsAsErrors>nullable</WarningsAsErrors>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0-preview.7.23330.2" />
  </ItemGroup>

</Project>

(Isn't projecting to a non-entity type AsNoTracking() anyway?)

@ajcvickers
Copy link
Member

@alienwareone The code you posted does not throw any exception when I run it.

@alienwareone
Copy link
Author

Thanks for testing this @ajcvickers

Seems like it has been fixed #31364. I've just tested this with .NET 8 RC1 and it works.

@ajcvickers ajcvickers added the closed-no-further-action The issue is closed and no further action is planned. label Sep 13, 2023
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Sep 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests

2 participants