2

NOT A DUPLICATE: My Update() methods takes two arguements: id and modified entity, and answers provided to my question have different approach like CurrentValues which isn't covered in existing questions.

I am new to ASP.Net core development. I am building a simple API with MySql as database and with a Book model.

I have written my controller like following:

[Route("api/[controller]")]
    public class BooksController : Controller
    {
        private readonly IBookRepository _books;
        public BooksController(IBookRepository books)
        {
            _books = books;
        }

        [HttpGet("")]
        public IActionResult GetAllBooks()
        {
            try
            {
                List<Book> books = _books.GetAllBooks();
                return Ok(books);
            }
            catch(EntityNotFoundException<Book>)
            {
                return NotFound();
            }

        }

        [HttpGet("{id}")]
        public IActionResult GetBook(long id)
        {
            Book book = _books.GetBook(id);
            if (book == null)
            {
                return NotFound();
            }
            return Ok(book);
        }

        [HttpPost]
        public IActionResult CreateBook([FromBody] Book book)
        {
            if (ModelState.IsValid == false)
            {
                return BadRequest(ModelState);
            }

            Book createdBook = _books.CreateBook(book);
            if (createdBook == null)
            {
                return NotFound();
            }
            return CreatedAtAction(
                 nameof(GetBook), new { id = createdBook.Id }, createdBook);

        }

        [HttpPut("{id}")]
        public IActionResult UpdateBook(long id, [FromBody] Book book)
        {
            if (ModelState.IsValid == false)
            {
                return BadRequest(ModelState);
            }

            try
            {
                _books.UpdateBook(id, book);
                return Ok();
            }
            catch (EntityNotFoundException<Book>)
            {
                return NotFound();
            }
        }

        [HttpDelete("{id}")]
        public IActionResult DeleteBook(long id)
        {
            _books.DeleteBook(id);
            return Ok();
        }
    } 

And Repository as following:

public class BookRepository: IBookRepository
    {
        private readonly WebAPIDataContext _db;

        public BookRepository(WebAPIDataContext db) {
            _db = db;
        }

        public Book CreateBook(Book book) {
            _db.Books.Add(book);
            _db.SaveChanges();
            return book;
        }

        public void DeleteBook(long id)
        {
            Book book = GetBook(id);
            if (book != null) {
                _db.Books.Remove(book);
                _db.SaveChanges();
            }
        }

        public List<Book> GetAllBooks()
        {
            return _db.Books.AsNoTracking().ToList();
        }

        public Book GetBook(long id)
        {
            return _db.Books.FirstOrDefault(o => o.Id == id);
        }

        public void UpdateBook(long id, Book book)
        {


        }
    }

    public interface IBookRepository
    {
        List<Book> GetAllBooks();
        Book GetBook(long id);
        Book CreateBook(Book book);
        void UpdateBook(long id, Book book);
        void DeleteBook(long id);
    }

I am not sure how can I write the UpdateBook method in my Repo class. Can someone please help me with that? All the tutorial I saw were using single id parameter to UpdateBook() method, I am basically posting a json object as well along with entity id.

3
  • Possible duplicate of How to update record using Entity Framework 6? Commented Mar 17, 2017 at 8:54
  • It isn't exact duplicate because my Update method takes two arguments wiz id and modified Entity and I did not find any tutorial or blogpost that does update like this. I think it is more convenient to update the entire entity rather than updating all it's properties one by one Commented Mar 17, 2017 at 8:57
  • It says "Possible duplicate" secondly, if you look into that post it clearly shows to get the entity from the database using id, then set its properties from the one you want to update, then save back into the database. It doesnt matter if you are posting a json object, at the dataAccess level / repository layer its just a POCO object. Commented Mar 17, 2017 at 9:18

3 Answers 3

8

Try this

  public void UpdateBook(long id, Book book)
  {  
     var originalBook=  _db.Books.FirstOrDefault(o => o.Id == id);
     _db.Entry(originalBook).CurrentValues.SetValues(book);
     _db.SaveChanges();
  }

Kindly note that you have to use EFcore version 1.1 for this to work

Sign up to request clarification or add additional context in comments.

9 Comments

It says EntityEntry<Book> doesn't contain a definition for CurrentValues also there is nothing to import when I mouseover
it seems CurrentValues method is still not implemented in .net core , if you want you could use this(stackoverflow.com/questions/36369233/…) extension method
Okay, but it won't break any other dependencies right? I am absolutely new to ASP.net core development, rather this is my very first attempt!
I have like this: "Microsoft.EntityFrameworkCore": "1.0.0", "MySql.Data.Core": "7.0.4-IR-191", "MySql.Data.EntityFrameworkCore": "7.0.6-IR31",
make it "Microsoft.EntityFrameworkCore": "1.1.0" and run restore package
|
1

The simplest way, you just load book from the database. Update fields and save changes to the database.

Book existingBook = GetBook(id);
existingBook.Title = book.Title;
// other properties
_db.SaveChanges();

4 Comments

Isn't there any way to directly map somehow the fetched entity as per the id to the the received entity? Because not necessarily all the fields will be updated.
you can use AutoMapper for mapping the fields.
This answer works, however I am interested to see how _db.Entry(originalBook).CurrentValues.SetValues(book); will work in this case as it is eliminated the need to remember and specify the attributes while updating
@Nitish I believe there should be the way to attach your new entity to the context as changed, so you can avoid loading the object first. I will try to find it.
1

I think Update method should do what you want. High-level idea is to attach entity and set its state to modified which is exactly what Update method does.

// Make sure that Book id is set correctly.
book.Id = id;
_db.Books.Update(book);
_db.SaveChanges();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.