'ef core 3.1 delete tracking

I'm getting the following unhandle exception when updating an object in my database.

InvalidOperationException: The instance of entity type 'DataloggerBrand' cannot be tracked because another instance with the key value '{Id: 3}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

I'm using .net core 3.1 and ef core 3.1 (this cannot change do to the assigned of this schoolproject)

I have following code in my controller:

if (ModelState.IsValid)
{
    List<InfluxTechnologyDatalogger> influxTechnologyDataloggers = new List<InfluxTechnologyDatalogger>();
    influxTechnologyDataloggers = GetActiveInfluxLoggers();
    DataloggerBrand dataloggerBrand = _context.DataloggerBrands.AsNoTracking().FirstOrDefault(x => x.Id == 3);

    foreach (var influxTechnologyDatalogger in influxTechnologyDataloggers)
    {
        InfluxTechnologyDatalogger selectedInfluxDatalogger = new InfluxTechnologyDatalogger();
        selectedInfluxDatalogger = _context.InfluxTechnologyDataloggers.AsNoTracking()
            .Include(x => x.DataloggerBrand)
            .Include(x => x.DataloggerState)
            .FirstOrDefault(x => x.SerialNumber == influxTechnologyDatalogger.SerialNumber);

        if (!_context.InfluxTechnologyDataloggers.Any(x => x.SerialNumber == influxTechnologyDatalogger.SerialNumber))
        {
            DataloggerState newDataloggerState = new DataloggerState();
            newDataloggerState = _context.DataloggerStates.AsNoTracking().FirstOrDefault(x => x.Name == "Choose State");

            _context.Add(new InfluxTechnologyDatalogger()
            {
                DataloggerBrand = dataloggerBrand,
                DataloggerState = newDataloggerState,
                SerialNumber = influxTechnologyDatalogger.SerialNumber,
                VHMeasureNumber = influxTechnologyDatalogger.VHMeasureNumber,
                LastContact = influxTechnologyDatalogger.LastContact,
                FreeSpaceOnSDCard = influxTechnologyDatalogger.FreeSpaceOnSDCard,

            });
        }
        else
        {
            InfluxTechnologyDatalogger editedInfluxTechnologyDatalogger = new InfluxTechnologyDatalogger()
            {
                Id = selectedInfluxDatalogger.Id,
                DataloggerBrand = selectedInfluxDatalogger.DataloggerBrand,
                DataloggerState = selectedInfluxDatalogger.DataloggerState,
                SerialNumber = selectedInfluxDatalogger.SerialNumber,
                VHMeasureNumber = selectedInfluxDatalogger.VHMeasureNumber,
                LastContact = influxTechnologyDatalogger.LastContact,
                FreeSpaceOnSDCard = influxTechnologyDatalogger.FreeSpaceOnSDCard
            };
            _context.Update(editedInfluxTechnologyDatalogger);
        }
        _context.SaveChanges();
    }
}

My question how can I get past this issue? The .AsNoTracking() is not helping.



Solution 1:[1]

There is the possibility to detach a context entry. I also cleaned up the code.

"" if (ModelState.IsValid) { List influxTechnologyDataloggers = new List(); influxTechnologyDataloggers = GetActiveInfluxLoggers(); DataloggerBrand dataloggerBrand = _context.DataloggerBrands.Find(3);

            foreach (var influxTechnologyDatalogger in influxTechnologyDataloggers)
            {
                InfluxTechnologyDatalogger selectedInfluxDatalogger = new InfluxTechnologyDatalogger();
                selectedInfluxDatalogger = _context.InfluxTechnologyDataloggers.AsNoTracking()
                    .FirstOrDefault(x => x.SerialNumber == influxTechnologyDatalogger.SerialNumber);
                Datalogger selectedDatalogger = new Datalogger();
                selectedDatalogger = _context.Dataloggers.AsNoTracking().Include(x => x.DataloggerState)
                    .FirstOrDefault(x => x.SerialNumber == influxTechnologyDatalogger.SerialNumber);
                DataloggerState dataloggerState =
                (selectedDatalogger == null || selectedDatalogger.DataloggerState == null) ?
                _context.DataloggerStates.Find(5) : selectedDatalogger.DataloggerState;
                int selectedId = (selectedInfluxDatalogger == null) ? 0 : selectedInfluxDatalogger.Id;
                InfluxTechnologyDatalogger newInfluxTechnologyDatalogger = new InfluxTechnologyDatalogger()
                {
                    Id = selectedId,
                    DataloggerBrand = dataloggerBrand,
                    DataloggerState = dataloggerState,
                    SerialNumber = influxTechnologyDatalogger.SerialNumber,
                    VHMeasureNumber = influxTechnologyDatalogger.VHMeasureNumber,
                    LastContact = influxTechnologyDatalogger.LastContact,
                    FreeSpaceOnSDCard = influxTechnologyDatalogger.FreeSpaceOnSDCard,
                    LastGPS = influxTechnologyDatalogger.LastGPS,
                    LastGPSLatitude = (influxTechnologyDatalogger.LastGPS == "") ? 0 : Conversion.GetLatitude(influxTechnologyDatalogger.LastGPS),
                    LastGPSLongitude = (influxTechnologyDatalogger.LastGPS == "") ? 0 : Conversion.GetLongitude(influxTechnologyDatalogger.LastGPS),
                    StreamlogDataloggerId = influxTechnologyDatalogger.StreamlogDataloggerId,
                    IsLogging = influxTechnologyDatalogger.IsLogging,
                    IsStreaming = influxTechnologyDatalogger.IsStreaming,
                    LastVRevisionID = influxTechnologyDatalogger.LastVRevisionID,
                    Diagnostic = influxTechnologyDatalogger.Diagnostic
                };

                _context.Update(newInfluxTechnologyDatalogger);
                if (selectedDatalogger != null)
                {
                    _context.Entry(selectedDatalogger.DataloggerState).State = EntityState.Detached;
                }
                _context.SaveChanges();
                newInfluxTechnologyDatalogger = null;
                dataloggerState = null;
            }
        } ""

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 RaJu