昨天調整完create和detail
今天繼續update和delete的部分
修改edit的部分和新增很類似
一樣有get 以及post的兩個同名的action
get的action主要是在點edit時帶入當下那個Product的資料
Post的action則是當點擊save時所發動的行為
一樣目前是直接使用DBContexct
在這裡要將它修改成呼叫ProductRepository裡面的方法
IProductRepository.cs
public bool UpdateProduct(Product product);
ProductRepository.cs
public bool UpdateProduct(Product product)
{
try
{
_context.Update(product); //使用DBContext的update
_context.SaveChanges();
return true;
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(product.Id)) //確認是否有存在這個id
{
return false;
}
else
{
throw;
}
}
}
private bool ProductExists(int id)
{
return _context.Products.Any(e => e.Id == id);
}
使用get 的action,一樣是和detail呼叫 GetProductById將該筆資料回傳到view中
// GET: Product/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var product = _productRepository.GetProductById(id.Value);
if (product == null)
{
return NotFound();
}
return View(product);
}
Post 方法的edit action
同樣的先判斷傳進來的id和Product是否相同
然後執行UpdateProduct去更新DB
這裡一樣要注意一下欄位名稱,如果有調整過要一併修改
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, [Bind("Id,ProductName,Price,Quty")] Product product)
{
if (id != product.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
if(_productRepository.UpdateProduct(product))
return RedirectToAction(nameof(Index));
else
return NotFound();
}
return View(product);
}
在使用Scaffold建出來的Delete action
和edit 相同有兩個同名的action
只是差在get和post方法
行為上是會先呼叫get的delete方法讓使用者確認要不要刪除
點下送出才會post到 delete的action
IProductRepository.cs
public void RemoveProduct(Product product);
ProductRepository.cs
public void RemoveProduct(Product product)
{
_context.Remove(product);
_context.SaveChangesAsync();
}
post的部分,透過傳進來的id,找到porduct後呼叫剛剛新增的RemoveProduct方法去做刪除
// POST: Product/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
var product = _productRepository.GetProductById(id);
_productRepository.RemoveProduct(product);
return RedirectToAction(nameof(Index));
}
其實CRUD的做法很像
主要都是透過Repository去操作DBContext
除了好管理外
也可以針對Model去做一些特別的處理判斷
而不用把這些邏輯寫在controller裡面