Update Data With Entry() Method In EF core

asp.net-core c# entity-framework-core

Question

I have editing data with entry method in ef core inside an async method. but when the program reaches the entry method throws an exception. exception message :

System.InvalidOperationException: 'The instance of entity type
'clinicSpecifications' cannot be tracked because another instance with the same key value for {'clinicSpecificationsID'} 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.'

this is my action:

[HttpPost("updateClinicSpecifications")]
public async Task<IActionResult> updateData(clinicSpecifications clinicSpecificationsParam, clinicOpeningHours clinicOpeningHoursParam)
{
    if (clinicSpecificationsParam.isActive == true)
    {
        await ClinicSpecificationsRepository.disableAllClinicAddress();

        //update AllAddress To Disable this update working correctly

        await ClinicSpecificationsRepository.saveChanges();
    }

    clinicSpecificationsParam.createDate = DateTime.Now.toShamsi();
    clinicOpeningHoursParam.createDate = DateTime.Now.toShamsi();

    //but when program reaches to this update exception is throws

    bool result = await ClinicSpecificationsRepository.editclinicSpecifications(clinicSpecificationsParam);

    bool result2 = await ClinicOpeningHoursRepository.editClinicOpeningHours(clinicOpeningHoursParam);

    if (result == true)
    {
        await ClinicSpecificationsRepository.saveChanges();
    }

    if (result2 == true)
    {
        await ClinicOpeningHoursRepository.saveChanges();
    }

    return RedirectToAction("Index");
}

this is disableAllClinicAddress method :

public async Task disableAllClinicAddress()
{
    var allAddress = await getAllClinicSpecifications();

    foreach (var item in allAddress)
    {
        item.isActive = false;
        await editclinicSpecifications(item);
    }
}

and my update method :

public async Task<bool> editclinicSpecifications(clinicSpecifications clinicSpecifications)
{
    try
    {
        await Task.Run(() => db.Entry(clinicSpecifications).State = EntityState.Modified);
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

please help me thanks.

1
0
3/11/2020 3:53:01 AM

Accepted Answer

I have editing data with entry method in ef core inside an async method. but when the program reaches the entry method throws an exception. exception message

Because you're creating a new instance (which isn't tracked) instead of updating the existing instance (which is tracked).Change like below:

var clinicSpecificationsParam = _dbcontext.clinicSpecifications.Find(id);

Here is a working demo I tested:

1.Model:

public class clinicSpecifications
{
    public int Id { get; set; }
    public bool isActive { get; set; }
    public DateTime createDate { get; set; }
}

2.Controller:

public class HomeController : Controller
{
    private readonly YourContext _context;

    public HomeController(YourContext context)
    {
        _context = context;
    }
    [HttpPost("updateClinicSpecifications")]
    public async Task<IActionResult> updateData(int id)
    {
        var clinicSpecificationsParam = _context.clinicSpecifications.Find(id);
        if (clinicSpecificationsParam.isActive == true)
        {
            await disableAllClinicAddress();

            await _context.SaveChangesAsync();
        }

        clinicSpecificationsParam.createDate = DateTime.Now;

        bool result = await editclinicSpecifications(clinicSpecificationsParam);
        //...
        return RedirectToAction("Index");
    }
    public async Task disableAllClinicAddress()
    {
        var allAddress = _context.clinicSpecifications.ToList();

        foreach (var item in allAddress)
        {
            item.isActive = false;
            await editclinicSpecifications(item);
        }
    }
    public async Task<bool> editclinicSpecifications(clinicSpecifications clinicSpecifications)
    {
        try
        {
            await Task.Run(() => _context.Entry(clinicSpecifications).State = EntityState.Modified);
            return true;
        }
        catch (Exception)
        {

            return false;
        }
    }

3.DbContext:

public class YourContext : DbContext
{
    public YourContext (DbContextOptions<YourContext> options)
        : base(options)
    {
    }

    public DbSet<clinicSpecifications> clinicSpecifications { get; set; }
}

Result: enter image description here

1
3/11/2020 4:29:00 AM

Popular Answer

In your update method, avoid using EntityState.Modified. I know it's a valid command but you can see you are having issues. You must first track the entry in question by doing a find or firstordefault to collect the record. Then you can modify the record and resave it. Here's some code off the top of my head but not tested.

var entry = db.ClinicSpecifications.FirstOrDefault(c => c.Id);
entry.Field = clinicSpecification.Field;
db.SaveChanges();

Again a rough example, but it works flawlessly.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow