Skip to content

Self-referencing entity circular dependency happening just on EF Core 6.0 #26750

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
josecu08 opened this issue Nov 18, 2021 · 4 comments
Closed

Comments

@josecu08
Copy link

Description

I'm not sure at all if this is a bug. At least I think is an unexpected behavior.
This behavior appeared for the first time after migrating to NET 6. I've managed to reproduce the issue in the simple project composed of the 3 files shown bellow. First I thought it was a breaking change so I reviewed all of them. However, I'm unable to find any breaking change that would cause this error. As I wasn't able to relate the error to any change I started changing efcore version in my .csproj file. As soon as I change to 6.0.0-rc.2.21480.5 for all the packages (efcore) the error doesn't show anymore. Another thing to highlight is that if I add a SaveChanges after the removes in the program.cs file the error won't happen either.

Person.cs

#nullable disable
public class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
    public int? ParentId { get; set; }
    public Person Parent { get; set; }


    protected Person()
    {
        
    }
    
    public Person(string name, Person parent)
    {
        this.Name = name;
        if (parent is not null)
        {
            this.Parent = parent;
        }
    }
}

Context.cs

#nullable disable
using Microsoft.EntityFrameworkCore;

public class Context : DbContext
{
    public Context()
    {}

    public DbSet<Person> Parents { get; set; }

    protected override void OnConfiguring(
            DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(
            "Data Source=DES04;Initial Catalog=Test;Integrated Security=true");        
        base.OnConfiguring(optionsBuilder);
    }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .HasOne(p => p.Parent)
            .WithMany()
            .IsRequired(false)
            .OnDelete(DeleteBehavior.Restrict);

        modelBuilder.Entity<Person>()
            .HasKey(p => p.PersonId);
    }
}

Program.cs

var context = new Context();

var parent = new Person("1", null);
var child1 = new Person("2", parent);
var child2 = new Person("3", parent);
var grandchild1 = new Person("4", child1);
var grandchild2 = new Person("5", child1);
var grandchild3 = new Person("6", child2);
var grandchild4 = new Person("7", child2);

context.Add(parent);
context.Add(child1);
context.Add(child2);
context.Add(grandchild1);
context.Add(grandchild2);
context.Add(grandchild3);
context.Add(grandchild4);
context.SaveChanges();


context.Remove(parent);
context.Remove(child1);
context.Remove(child2);
context.Remove(grandchild1);
context.Remove(grandchild2);
context.Remove(grandchild3);
context.Remove(grandchild4);

parent = new Person("1", null);
child1 = new Person("2", parent);
child2 = new Person("3", parent);
grandchild1 = new Person("4", child1);
grandchild2 = new Person("5", child1);
grandchild3 = new Person("6", child2);
grandchild4 = new Person("7", child2);

context.Add(parent);
context.Add(child1);
context.Add(child2);
context.Add(grandchild1);
context.Add(grandchild2);
context.Add(grandchild3);
context.Add(grandchild4);
context.SaveChanges();

Stack trace

Unhandled exception. System.InvalidOperationException: Unable to save changes because a circular dependency was detected in the data to be saved: 'Person [Deleted]Person [Deleted] Parent { 'ParentId' } <-
Person [Deleted] Parent { 'ParentId' } <-
Person [Deleted]To show additional information call 'DbContextOptionsBuilder.EnableSensitiveDataLogging'.'.
   at Microsoft.EntityFrameworkCore.Utilities.Multigraph`2.ThrowCycle(List`1 cycle, Func`2 formatCycle, Func`2 formatException)
   at Microsoft.EntityFrameworkCore.Utilities.Multigraph`2.BatchingTopologicalSort(Func`4 tryBreakEdge, Func`2 formatCycle)
   at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.TopologicalSort(IEnumerable`1 commands)
   at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BatchCommands(IList`1 entries, IUpdateAdapter updateAdapter)+MoveNext()
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
   at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList`1 entries)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList`1 entriesToSave)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(StateManager stateManager, Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<>c.<SaveChanges>b__104_0(DbContext _, ValueTuple`2 t)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
   at Program.<Main>$(String[] args) in C:\Users\Dev04\Desktop\Nueva carpeta\test\Program.cs:line 44

Version information

EF Core version:
Ef Core (Microsoft.EntityFrameworkCore 6.0.0)
Database provider: (Microsoft.EntityFrameworkCore.SqlServer 6.0.0)
Target framework: (.NET 6.0.0)

@ajcvickers
Copy link
Contributor

/cc @AndriySvyryd Throws on 6.0; does not throw on 5.0.

@jonasrdm
Copy link

I'm having the same issue in my project after the upgrade. Does it have any known workaround until a fix is released?

@ajcvickers
Copy link
Contributor

@jonasrdm We will investigate workarounds.

@fengqingtian
Copy link

I'm having the same issue in my project after the upgrade. Does it have any known workaround until a fix is released?
in my situation, I add another context.SaveChanges() before add, it works.

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

5 participants