2016-10-23 2 views
0

Я пытаюсь обновить объект, и я работать в следующей ошибки:Экземпляр типа объекта «BookLoan» не может быть отслежена

InvalidOperationException: The instance of entity type 'BookLoan' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context.

я сделал небольшое исследование, и от чего я может сказать, что я, по-видимому, пытаюсь отслеживать уже отслеживаемый объект, когда я использую _context.Update(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); 
     } 
    } 

Сообщение:

[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», получить существующий объект из базы данных на основе идентификатора (например, «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>), это вызовет исключение.

 Смежные вопросы

  • Нет связанных вопросов^_^