简体   繁体   中英

EF Core - Insert then update an entry

In a WebApi method I need, if an element not exist, insert it and after a few operations update it.

The code is the following:

Entry existingEntry = await _repo.GetEntryByIdAsync(id);

existingEntry = await _repo.AddNewEntryAsync(existingAccred);

// Some code...

// Update
existingAccred.IdField = myField;
await _repo.UpdateEntryAsync(existingEntry);

The repo is the following:

    public async Task<Entry> GetEntryByIdAsync(int myId)
    {
        var result = from entry in _ctx.Set<DALENTRY>()
            where entry.ID == myId
            select new Entry
            {
                ID = entry.IdEntry,
            };

        return await result.AsNoTracking().FirstOrDefaultAsync();
    }

    public async Task<Entry> AddNewEntryAsync(Entry newEntry)
    {
        DALENTRY entry = new DALENTRY()
        {
            GUID = newEntry.GUID,
        };

        _ctx.Add(entry);
        await _ctx.SaveChangesAsync();

        newEntry.IdEntry = entry.ID;

        return newEntry;
    }

    public async Task<Entry> UpdateEntryAsync(Entry updateEntry)
    {
        DALENTRY entry = new DALENTRY()
        {
            ID = updateEntry.IdEntry,
            FIELD= updateEntry.IdField,
        };

        _ctx.Update(entry);
        await _ctx.SaveChangesAsync();

        return updateEntry;
    }

But when I perform the update I'm getting is the following error:

An unhandled exception occurred while processing the request.

InvalidOperationException: The instance of entity type 'DALENTRY' cannot be tracked because another instance with the same key value for {'ID'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap.Add(TKey key, InternalEntityEntry entry)

The repo is registered as Transient like:

services.AddTransient<EntryRepository>();

I tried using Detach after the insert, but using it the update is clearing all the non updated fields. I can't remember what is causing this issue.

Solved changing my update strategy in the repo by read the entry first, then update it:

public async Task<Entry> UpdateEntryAsync(Entry updateEntry)
{
    DALENTRY entry = await _ctx.Set<DALENTRY >().SingleOrDefaultAsync(a => a.ID == updateEntry.IdEntry);

    entry.FIELD= updateEntry.IdField,

    _ctx.Update(entry);
    await _ctx.SaveChangesAsync();

    return updateEntry;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM