dotnet / dotnet/efcore

Unhandled exception when calling ExecuteUpdate on TPС hierarchy

Open
#36,216 1 comment 0 reactions 0 assignees View on GitHub
area-bulkupdate customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

### Bug description

An unhandled exception occurs when calling `ExecuteUpdateAsync` on a TPC hierarchy

### Your code

```csharp
using Microsoft.EntityFrameworkCore;

namespace NullabilityProcessorBug;

class Program
{
static async Task Main(string[] args)
{
await using (var context = new BugDbContext())
{
await context.Database.MigrateAsync();
context.Set().AddRange(_getSeedData());
await context.SaveChangesAsync();
}

await using (var context = new BugDbContext())
{
IQueryable itemsQuery = context.Set();

var list = await context
.Set()
.Select(x => new
{
Item = x,
Parent = itemsQuery.FirstOrDefault(parent => parent.Id == x.ParentId)
}
)
.Select(x => new
{
Item = x.Item,
Path = x.Item.ParentId.HasValue && x.Parent != null
? (LTree)(x.Parent.TreePath + "." + x.Item.Id.ToString().Replace("-", string.Empty).ToLower())
: (LTree)x.Item.Id.ToString().Replace("-", string.Empty).ToLower()
}
)
.ExecuteUpdateAsync(x => x
.SetProperty(
y => y.Item.TreePath,
y => y.Path
)
);
}

Console.WriteLine("Hello, World!");
}

private static IEnumerable _getSeedData()
{
return
[
new TreeItemA
{
Id = Guid.CreateVersion7(),
Children =
[
new TreeItemB
{
Id = Guid.CreateVersion7(),
},
new TreeItemB
{
Id = Guid.CreateVersion7(),
},
new TreeItemA
{
Id = Guid.CreateVersion7(),
Children =
[
new TreeItemB
{
Id = Guid.CreateVersion7(),
},
new TreeItemB
{
Id = Guid.CreateVersion7(),
}
]
}
]
}
];
}
}

class BugDbContext: DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql("Host=localhost;Database=NullabilityProcessorBug;Username=postgres;Password=postgres;Port=5432");
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder
.Entity()
.UseTpcMappingStrategy()
.HasMany(x => x.Children)
.WithOne()
.HasForeignKey(x => x.ParentId)
.IsRequired(false);

modelBuilder
.Entity();

modelBuilder.Entity();
modelBuilder.Entity();
}
}

abstract class TreeItem
{
public Guid Id { get; set; }

public Guid? ParentId { get; set; }

public LTree TreePath { get; set; } = new LTree("unsetted");

public IList Children { get; set; } = new List();
}

class TreeItemA: TreeItem;

class TreeItemB: TreeItem;
```

### Stack traces

```text
System.InvalidOperationException: Unhandled expression '[Microsoft.EntityFrameworkCore.Query.Internal.TpcTablesExpression]' of type 'Microsoft.EntityFrameworkCore.Query.Internal.TpcTablesExpression' encountered in 'SqlNullabilityProcessor'.
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(TableExpressionBase tableExpressionBase)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SelectExpression selectExpression, Boolean visitProjection)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SelectExpression selectExpression)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.VisitExists(ExistsExpression existsExpression, Boolean allowOptimizedExpansion, Boolean& nullable)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SqlExpression sqlExpression, Boolean allowOptimizedExpansion, Boolean preserveColumnNullabilityInformation, Boolean& nullable)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.VisitSqlBinary(SqlBinaryExpression sqlBinaryExpression, Boolean allowOptimizedExpansion, Boolean& nullable)
at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlNullabilityProcessor.VisitSqlBinary(SqlBinaryExpression sqlBinaryExpression, Boolean allowOptimizedExpansion, Boolean& nullable)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SqlExpression sqlExpression, Boolean allowOptimizedExpansion, Boolean preserveColumnNullabilityInformation, Boolean& nullable)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.VisitCase(CaseExpression caseExpression, Boolean allowOptimizedExpansion, Boolean& nullable)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SqlExpression sqlExpression, Boolean allowOptimizedExpansion, Boolean preserveColumnNullabilityInformation, Boolean& nullable)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SqlExpression sqlExpression, Boolean allowOptimizedExpansion, Boolean& nullable)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SqlExpression sqlExpression, Boolean& nullable)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.VisitUpdate(UpdateExpression updateExpression)
at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Process(Expression queryExpression, IReadOnlyDictionary`2 parameterValues, Boolean& canCache)
at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlParameterBasedSqlProcessor.ProcessSqlNullability(Expression selectExpression, IReadOnlyDictionary`2 parametersValues, Boolean& canCache)
at Microsoft.EntityFrameworkCore.Query.RelationalParameterBasedSqlProcessor.Optimize(Expression queryExpression, IReadOnlyDictionary`2 parametersValues, Boolean& canCache)
at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlParameterBasedSqlProcessor.Optimize(Expression queryExpression, IReadOnlyDictionary`2 parametersValues, Boolean& canCache)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalCommandCache.GetRelationalCommandTemplate(IReadOnlyDictionary`2 parameters)
at lambda_method60(Closure, IReadOnlyDictionary`2)
at Microsoft.EntityFrameworkCore.Internal.RelationalCommandResolverExtensions.RentAndPopulateRelationalCommand(RelationalCommandResolver relationalCommandResolver, RelationalQueryContext queryContext)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.<>c.b__32_0(DbContext _, ValueTuple`3 state, CancellationToken cancellationToken)
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at NullabilityProcessorBug.Program.Main(String[] args) in D:\_repos\NullabilityProcessorBug\NullabilityProcessorBug\Program.cs:line 20
at NullabilityProcessorBug.Program.Main(String[] args) in D:\_repos\NullabilityProcessorBug\NullabilityProcessorBug\Program.cs:line 42
at NullabilityProcessorBug.Program.(String[] args)
```

### Verbose output

```text

```

### EF Core version

9.0.5

### Database provider

Npgsql.EntityFrameworkCore.PostgreSQL

### Target framework

.NET 9.0

### Operating system

Windows 11

### IDE

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.