Home > OS >  How to fix DbUpdateConcurrencyException when removing multiple entries?
How to fix DbUpdateConcurrencyException when removing multiple entries?

Time:09-17

I receive this error when trying to remove entries from the table with EFC

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 30 row(s); data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.

This is my code:

https://paste.mod.gg/xlynuworjmmf/0

using MySqlConnector;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using MySql.EntityFrameworkCore;

namespace Flanium_Agent
{
public class AgentContext : DbContext
{
    public DbSet<Agent> agent { get; set; }
    public DbSet<AgentRequest> agentRequest { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseMySQL("Server=localhost;User ID=root;Database=orchestration_db");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Agent>().HasKey(a => a.Station);
        modelBuilder.Entity<Agent>().ToTable("agents");
        modelBuilder.Entity<AgentRequest>().HasKey(a => a.Station);
        modelBuilder.Entity<AgentRequest>().ToTable("agent_requests");
    }
}

public class Agent
{
    public string Station { get; set; }
    public string Process { get; set; }
    public string Actions { get; set; }
    public string Started { get; set; }
    public string Finished { get; set; }
    public string Status { get; set; }
}

public class AgentRequest
{
    public string Station { get; set; }
    public string Request { get; set; }
}

public class Agency : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    private bool ProcessRunning = false;
    private List<string> RequestList = new List<string>();
    public string Station { get; set; }
    public string Process { get; set; }
    public string Actions { get; set; }
    public string Started { get; set; }
    public string Finished { get; set; }
    public string Status { get; set; }
    public string Request { get; set; }
    
    private Grid DisplayGrid { get; set; }
    private Window appWindow { get; set; }

    public Grid GetDisplayGrid()
    {
        return DisplayGrid;
    }

    public Agency InsertAgentToGrid(Window mainWindow)
    {
        DisplayGrid = new Grid();

        var headerRowDefinition = new RowDefinition();
        headerRowDefinition.Height = new GridLength(50);
        DisplayGrid.RowDefinitions.Add(headerRowDefinition);

        for (var index = 0; index < GetType().GetProperties().Length; index  )
        {
            var property = GetType().GetProperties()[index];
            var header = new TextBlock();
            var column = new ColumnDefinition();
            header.Text = property.Name;
            header.HorizontalAlignment = HorizontalAlignment.Center;
            header.VerticalAlignment = VerticalAlignment.Center;
            header.FontSize = 16;
            header.FontWeight = FontWeights.Medium;
            Grid.SetRow(header, 0);
            Grid.SetColumn(header, index);

            DisplayGrid.ColumnDefinitions.Add(column);
            DisplayGrid.Children.Add(header);
        }

        var contentRowDefinition = new RowDefinition();
        contentRowDefinition.Height = GridLength.Auto;
        DisplayGrid.RowDefinitions.Add(contentRowDefinition);

        for (var index = 0; index < GetType().GetProperties().Length; index  )
        {
            var propertyValue = GetType().GetProperties()[index];
            var content = new TextBlock();

            content.HorizontalAlignment = HorizontalAlignment.Center;
            content.VerticalAlignment = VerticalAlignment.Center;
            content.FontSize = 12;
            content.TextWrapping = TextWrapping.Wrap;
            Grid.SetRow(content, 1);
            Grid.SetColumn(content, index);
            DisplayGrid.Children.Add(content);

            var myBinding = new Binding(propertyValue.Name)
            {
                Source = this,
                Mode = BindingMode.TwoWay,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };
            content.SetBinding(TextBlock.TextProperty, myBinding);
        }

        DisplayGrid.HorizontalAlignment = HorizontalAlignment.Stretch;
        DisplayGrid.VerticalAlignment = VerticalAlignment.Top;
        DisplayGrid.Margin = new Thickness(0, 25, 0, 0);
        (mainWindow.Content as Grid).Children.Add(DisplayGrid);
        appWindow = mainWindow;


        return this;
    }


    private string[] GetPackages()
    {
        var packagesArray = new List<string>();

        var desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        var pathString = Path.Combine(desktopPath, "Flanium Agent Data");
        var packageFolders = Directory.GetDirectories(pathString);
        foreach (var packFolder in packageFolders)
        {
            var versions = Directory.GetDirectories(packFolder);
            if (versions.Length != 0)
            {
                packagesArray.AddRange(versions.Select(version => version.Split('\\').Last())
                    .Select(versionName => packFolder.Split('\\').Last()   "\\"   versionName));
                packagesArray = packagesArray.Select(x => x = pathString   "\\"   x).ToList();
            }
        }

        return packagesArray.ToArray();
    }

    public Agency(string station, string process, string actions, string started, string finished, string status)
    {
        try
        {
            using (var context = new AgentContext())
            {
                context.agent.Add(new Agent
                    {Station = station, Process = process, Actions = actions, Started = started, Finished = finished, Status = status});
                // Saves changes
                context.SaveChanges();
            }
            
            Station = station;
            Process = process;
            Actions = actions;
            Started = started;
            Finished = finished;
            Status = status;
        }
        catch (Exception e)
        {
            
        }
    }

    public void RemoveAgent()
    {
        using (var context = new AgentContext())
        {
            context.agent.Where(x=> x.Station == Station).ToList().ForEach(x=> context.agent.Remove(x));
            // Saves changes
            context.SaveChanges();
        }
        
    }
}
}

I followed a tutorial on the internet on how to use EFC by the teeth and for some euclidean reason, as always, the code works for others and the same code does not work when I try it out.

CodePudding user response:

modelBuilder.Entity<Agent>().HasKey(a => a.Station);

So you have an entity Agent, about which you tell Entity Framework that it has a primary key column named "station".

You have a database with at least 30 records in it, and at least 30 of those records have the same value for the station column.

So despite you telling EF that station is the primary key, it isn't. So EF generates the query:

DELETE FROM agent WHERE station=@station

And the database engine happily removes all 30 records for which the station equals the station of the first record it encounters, and reports this, then EF throws, because it expected one record to be deleted, not 30.

The solution: configure the actual primary key as key, or if there isn't any, create one.

  • Related