dotnet / dotnet/efcore

Non-trivial AutoInclude cycle is need detected, and still causes stack overflow

Open
#36,321 3 comments 0 reactions 0 assignees View on GitHub
area-query customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

### Bug description

I'm trying to model a situation where "users" have two kinds of "groups" they can belong to. For convenience, I use `AutoInclude` in all relationships. I want to delete orphaned groups, i.e., those without users, so I use `ExecuteDelete` on groups whose user count is zero.

The call to `ExecuteDelete` below causes a stack overflow.

Commenting one any of the 4 lines that call `AutoInclude()` "fixes" it (in the sense there's no stack overflow, but then of course the behavior changes).

### Your code

```xml


Exe
net9.0
disable
enable




```

```csharp
using System.Collections.Generic;
using System.IO;
using System.Linq;

using Microsoft.EntityFrameworkCore;

var optionsBuilder = new DbContextOptionsBuilder();
optionsBuilder.UseSqlite($"DataSource=" + Path.Combine(Directory.CreateTempSubdirectory().FullName, "db"));
var context = new MyDbContext(optionsBuilder.Options);
context.Database.EnsureCreated();

context.FirstGroups.Where(a => a.FirstMembers.Count == 0).ExecuteDelete();

class User
{
public int Id { get; set; }
public FirstGroup? FirstGroup { get; set; }
public SecondGroup? SecondGroup { get; set; }
}

class FirstGroup
{
public int Id { get; set; }
public ISet FirstMembers { get; } = new HashSet();
}

class SecondGroup
{
public int Id { get; set; }
public ISet SecondMembers { get; } = new HashSet();
}

class MyDbContext(DbContextOptions options) : DbContext(options)
{
public DbSet Users { get; set; }
public DbSet FirstGroups { get; set; }
public DbSet SecondGroups { get; set; }

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

modelBuilder.Entity().HasOne(p => p.FirstGroup).WithMany(p => p.FirstMembers);
modelBuilder.Entity().Navigation(p => p.FirstGroup).AutoInclude();

modelBuilder.Entity().HasOne(p => p.SecondGroup).WithMany(p => p.SecondMembers);
modelBuilder.Entity().Navigation(p => p.SecondGroup).AutoInclude();

modelBuilder.Entity().Navigation(p => p.FirstMembers).AutoInclude();

modelBuilder.Entity().Navigation(p => p.SecondMembers).AutoInclude();
}
}
```

### Stack traces

The repeating bit is:
```text
at Microsoft.EntityFrameworkCore.Query.IncludeExpression.VisitChildren(System.Linq.Expressions.ExpressionVisitor)
at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor+PendingSelectorExpandingExpressionVisitor.Visit(System.Linq.Expressions.Expression)
at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor+PendingSelectorExpandingExpressionVisitor.Visit(System.Linq.Expressions.Expression)
at Microsoft.EntityFrameworkCore.Query.MaterializeCollectionNavigationExpression.VisitChildren(System.Linq.Expressions.ExpressionVisitor)
```

### Verbose output

```text

```

### EF Core version

9.0.6

### Database provider

Microsoft.EntityFrameworkCore.Sqlite

### Target framework

.NET 9.0

### Operating system

Windows 11

### IDE

Visual Studio 2022 17.14.7

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.