c# - 无法跟踪实体类型 'BookLoan' 的实例

标签 c# asp.net-mvc entity-framework asp.net-core entity

我正在尝试更新一个实体,但遇到了以下错误:

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 Controller ,因为我不确定还有什么要分享。

获取

    [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();
    }

最佳答案

您的上下文已经包含该实体,因此与其创建一个新实体,不如根据该实体的 ID 获取现有实体并更新其属性,然后保存它

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");
    }
    ....

旁注:返回 View 时,最好使用 return View(model); 传回模型- 即使您不这样做,您的表单控件也会被正确填充(因为它们从 ModelState 获取值),但是如果您有任何对模型属性的引用(例如 <div>@Model.someProperty</div>),它会抛出异常。

关于c# - 无法跟踪实体类型 'BookLoan' 的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40198433/

相关文章:

c# - .net 标准 1.3 项目中的 log4net 配置

c# - 为什么使用 as 关键字初始化对象

wpf - 使用Entity Framework 4创建Blob属性吗?

c# - asp.net core 如何阻止 http 请求锁定

c# - 删除在运行时 CF C# 上创建的标签

javascript - 不使用 javascript 检查表单数据的更改

asp.net-mvc - Azure SignalR 了解连接计数

javascript - 固定 header 脚本函数 floatHead 正在添加一个额外的 thead

entity-framework - 手动 DAL & BLL 与 ORM

c# - 如果我将 virtual 关键字添加到属性,我需要帮助解决为什么 Entity Framework 不会保存