简体   繁体   中英

Not updating object on database ASP.net core 2.0

I am having a little issue that I cannot fully comprehend.

On my controller I have:

        [HttpPut("{id}")]
    public async Task<IActionResult> PutExercise([FromRoute] int id, [FromBody] Exercise exercise)
    {
        logger.LogInformation("Updating item {ID}", id);
        if (!ModelState.IsValid)
            return BadRequest(ModelState);            

        if (id != exercise.ExerciseId)
            return BadRequest();

        var baseExercise = await repository.GetExercise(id);
        if (baseExercise == null)
            return NotFound(id);

        baseExercise = exercise;
        await unitOfWork.CompleteAsync();

        return NoContent();
    }

but it is NOT updating on the database with the values provided on the PUT body request. Although on memory they are changed, the object is not pushed... But if I set a breakpoint on await unitOfWork.CompleteAsync(); and then modify baseExercise with the debugger, it does update. Why is this happening?

    public class UnitOfWork : IUnitOfWork
{
    private readonly FitaholicContext context;

    public UnitOfWork(FitaholicContext context)
    {
        this.context = context;
    }
    public Task CompleteAsync()
    { 
        return context.SaveChangesAsync();
    }
}

--

public async Task<Exercise> GetExercise(int id, bool includeRelated = false)
    {
        if (!includeRelated)
            return await context.Exercise.SingleOrDefaultAsync(m => m.ExerciseId == id);

        return await context.Exercise
                    .Include(e => e.Equipments)
                        .ThenInclude(ee => ee.Equipment)
                    .Include(e => e.TypeRecord)
                    .SingleOrDefaultAsync(m => m.ExerciseId == id);
    }

You should using async/await in the function:

    public async Task CompleteAsync()
    { 
        await context.SaveChangesAsync();
    }

You are missing the link between the Repository and the UnitOfWork. In order to get the pattern working, and then persist your data, you should only access the repository's methods the unit of work, ie the UoW should be just a wrapper for all the repositories related to one database, with the extra purpose of maintaining your data consistency. 工作单元访问存储库的方法,即,UoW应该只是与一个数据库相关的所有存储库的包装,另外还有维护目的您的数据一致性。
In the controller your first retrieve baseExercise via repository.GetExercise(id) , then you're trying to persist the data with unitOfWork.CompleteAsync() . The problem is that you didn't instruct the uniOfWork to care about the repository behaviour.
That said, it should be a quick fix.
First, set the first part of the link in the UnitOfWork :

public class UnitOfWork : IUnitOfWork
{
    private readonly FitaholicContext context;

    public UnitOfWork(FitaholicContext context)
    {
        this.context = context;
    }

    private Repository _repository;
    public Repository repository =>
        this._repository ?? (this._repository =
            new Repository(this.context));

    public Task CompleteAsync()
    { 
        return context.SaveChangesAsync();
    }
}

Then the second half, in the Repository :

public class Repository
{
     public Repository(FitaholicContext context)
     { }

     public async Task<Exercise> GetExercise(int id, bool includeRelated = false)
     { ... }
 }  

Last step, update PutExercise() in the controller to reflect the logic changes:

[HttpPut("{id}")]
public async Task<IActionResult> PutExercise([FromRoute] int id, [FromBody] Exercise exercise)
{
    ...

    var baseExercise = await this.unitOfWork.repository.GetExercise(id);

    ...

    await this.unitOfWork.CompleteAsync();

    return NoContent();
}  

If you need to dig a bit deeper into the Repository-UnitOfWork pattern, check the Microsoft Docs .

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