sharp328
sharp328

Reputation: 145

Database operation expected to affect 1 row(s) but actually affected 0 row(s). Entity's collection not tracked?

I'm getting this error:

Database operation expected to affect 1 row(s) but actually affected 0 row(s)

when adding a new element to the entity's collection.

Base classes in Domain project:

public class Tour
{
        private List<Stop> _stops;
        
        public Guid Id { get; private set; }

        public Tour(Guid id)
        {
            Id = id;
            _stops = new List<Stop>();
        }

        public IReadOnlyList<Stop> Stops { get { return _stops; } }
        
        public void AddStop(Stop newStop)
        {
            //some logic and checking
            _stops.Add(newStop);
        }
}

public class Stop
{
        public Stop(Guid id)
        {
            Id = id;
        }

        public Guid Id { get; private set; }
}

My DbContext in the Infrastructure project:

public class TourDbContext : DbContext, ITourDbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=db");
    }
    
    public DbSet<Tour> Tours { get; set; }
    public DbSet<Stop> Stops { get; set; }
}

Exception is thrown when calling AddStopToTour() in the Application project.

Interface for DbContext, based on: https://github.com/jasontaylordev/CleanArchitecture.

public interface ITourDbContext
{
    public DbSet<Tour> Tours { get; set; }
    public DbSet<Stop> Stops { get; set; }
    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}

public class SomeClass
{
    ITourDbContext _context;

    public SomeClass(ITourDbContext context) 
    {
        _context = context;
    }

    public async Task AddStopToTour(Guid id)
    {
        var tour = await _context.Tours
                                 .Include(x => x.Stops)
                                 .SingleOrDefaultAsync(e => e.Id == id);

        tour.AddStop(new Stop(Guid.NewGuid());
        await _context.SaveChangesAsync(); //Exception
    }
}

Shouldn't EF Core be able to track these changes automatically and add 1 new row to the Stops table? Am I missing additional configuration on entities?

Upvotes: 2

Views: 2477

Answers (1)

sharp328
sharp328

Reputation: 145

The problem was that by generating my Id's manually, the new entity got the Modified state, instead of Added state. The fix was using the Fluent API's .ValueGeneratedNever() method with the modelBuilder.

See: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.x/breaking-changes#detectchanges-honors-store-generated-key-values

Upvotes: 8

Related Questions