2016-10-23 21 views
0

を追跡することはできません_context.Update(bookloan);を使用すると、すでに追跡されているエンティティを追跡しようとしているように見えますが、何をすべきかはわかりません。エンティティタイプ「BookLoan」のインスタンスは、私は、エンティティを更新しようとしていると私は、次のようなエラーに遭遇しました

私がやっていることは、自分のデータベースの既存のエンティティ/レコードを更新することです。ここにはgetとpostのコントローラがあります。私は他に何を共有するか分かりません。

[HttpGet] 
    public async Task<IActionResult> Return(int? id) 
    { 
     if (id == null) 
     { 
      return NotFound(); 
     } 

     if (isBookCheckedOut(id) == false) 
     { 
      //Not checked out 
      return RedirectToAction("Index"); 
     } 
     else 
     { 
      var bookloan = (from book in _context.Books.Where(b => b.BookId == id) 
         join loan in _context.BookLoans.Where(x => !x.ReturnedOn.HasValue) on book.BookId equals loan.BookID into result 
         from loanWithDefault in result.DefaultIfEmpty() 
         select new BookReturnViewModel 
         { 
          BookLoanID = loanWithDefault.BookLoanID, 
          BookID = book.BookId, 
          Title = book.Title, 
          StudentID = loanWithDefault == null ? null : loanWithDefault.StudentID, 
          StudentFristName = loanWithDefault == null ? null : loanWithDefault.Student.FirstName, 
          StudentLastName = loanWithDefault == null ? null : loanWithDefault.Student.LastName, 
          //Fines 
          CheckedOutOn = loanWithDefault == null ? (DateTime?)null : loanWithDefault.CheckedOutOn, 
          IsAvailable = loanWithDefault == null, 
          AvailableOn = loanWithDefault == null ? (DateTime?)null : loanWithDefault.DueOn 
         }).FirstOrDefault(); 

      if (bookloan == null) 
      { 
       return NotFound(); 
      } 

      return View(bookloan); 
     } 
    } 

ポストゲット:あなたのコンテキストがすでにそうではなく、新しいものを作成することは、エンティティのIDに基づいて、既存のものを取得し、そのを更新することを、エンティティを含ん

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Return(BookReturnViewModel model) 
    { 


     if (ModelState.IsValid && isBookCheckedOut(1) == true) 
     { 
      var bookloan = new BookLoan() 
      { 
       BookLoanID = model.BookLoanID, 
       BookID = model.BookID, 
       StudentID = model.StudentID, 
       CheckedOutOn = (DateTime)model.CheckedOutOn, 
       DueOn = (DateTime)model.AvailableOn, 
       ReturnedOn = DateTime.Now 
      }; 


      try 
      { 

       _context.Update(bookloan); 
       await _context.SaveChangesAsync(); 
      } 
      catch (DbUpdateConcurrencyException) 
      { 

      } 

      return RedirectToAction("Index"); 
     } 
     else 
     { 

     } 

     return View(); 
    } 
+1

新しい「BookLoan」の代わりに、IDに基づいてデータベースから既存のエンティティを取得します(例: 'BookLoan data = db.BookLoans.Where(x => x.BookLoanID == model.BookLoanID)。 FirstOrDefault(); ')、ビューモデルに基づいてそのプロパティを更新して保存します。 –

+0

ありがとう、それは完璧に働いた!私は答えとしてマークしたいと思いますが、私はコメントのためにそれを行うことはできません。私がそれをやろうとしていたのは、足場を使った編集が行われたときにEntityが見たことを模倣したことだけでした。 –

答えて

2

をプロパティを保存してから保存してください。

if (ModelState.IsValid && isBookCheckedOut(1) == true) 
{ 
    // Get the existing entity 
    BookLoan bookLoan = db.BookLoans.Where(x => x.BookLoanID == model.BookLoanID).FirstOrDefault(); 
    if (bookLoan != null) 
    { 
     bookLoan.BookID = model.BookID; 
     bookLoan.StudentID = model.StudentID; 
     .... // update other properties as required 
     _context.Update(bookloan); 
     await _context.SaveChangesAsync(); 
     return RedirectToAction("Index"); 
    } 
    .... 

サイドノート:ビューを返すときは、モデルをreturn View(model);を使用して作成すると、フォームコントロールが正しく設定されません(値がModelStateになるため)。ただし、モデルプロパティ(例: <div>@Model.someProperty</div>)、例外がスローされます。

関連する問題