【问题标题】:Not able to update the data using entity framework无法使用实体框架更新数据
【发布时间】:2017-01-14 13:35:01
【问题描述】:

我有以下代码。我正在尝试更新我的数据。但我收到错误消息:

EntityFramework.dll 中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理

附加信息:ObjectStateManager 中已存在具有相同键的对象。 ObjectStateManager 无法跟踪具有相同键的多个对象。

这是我的代码:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include="CompanyId,Address,EstbalishYear,Email,IsActive")] CompanyMaster companymaster)
    {
        if (companymaster.CompanyId == 0)
        {
            return View(companymaster);
        }
        CompanyMaster company = db.CompanyMasters.SingleOrDefault(x => x.CompanyId == companymaster.CompanyId);
        companymaster.Name = company.Name;
        companymaster.InsertedBy = company.InsertedBy;
        companymaster.InsertedTime = company.InsertedTime;
        companymaster.UpdatedBy = 1;
        companymaster.UpdatedTime = DateTime.Now;

        ModelState.Remove("Name");

        if (ModelState.IsValid)
        {
            db.Entry(companymaster).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(companymaster);
    }

请解释一下如何解决此错误消息?

【问题讨论】:

    标签: asp.net-mvc entity-framework


    【解决方案1】:

    这是因为您正在使用公司主对象的 两个 对象实例,实际上是一个具有相同 ID 的实体。

    One (companyMaster) 通过绑定作为 Edit 方法的参数。

    您正在通过 db.CompanyMasters by ID 从数据库中选择的另一个(公司

    你能做的是

    1. 像现在一样按 ID 选择公司
    2. 从 companyMaster 对象设置公司属性(反之亦然,不像现在这样)
    3. 保存公司对象

    请在下面找到示例代码。 另请注意,最佳实践不是在 UI 层使用您的持久性实体模型,而是使用最少的必填字段集定义一个 DTO,然后手动或使用 AutoMapper 将其映射到您的实体。

        [HttpPost] [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include="CompanyId,Address,EstbalishYear,Email,IsActive")] CompanyMaster companymaster)
    
        {
            if (companymaster.CompanyId == 0)
            {
                return View(companymaster);
            }
            CompanyMaster company = db.CompanyMasters.SingleOrDefault(x => x.CompanyId == companymaster.CompanyId);
            company.Address = companymaster.Address;
            company.EstbalishYear= companymaster.EstbalishYear;
            company.Email = companymaster.Email;
            company.IsActive= companymaster.IsActive;
            company.UpdatedBy = 1;
            company.UpdatedTime = DateTime.Now;
    
            ModelState.Remove("Name");
    
            if (ModelState.IsValid)
            {
                db.SaveChanges();
                return RedirectToAction("Index");
            }
    
            return View(companymaster);
        }
    

    【讨论】:

    • 谢谢。我明白了你的意思,但我有一个疑问。我想从数据库中获取名称字段值。那我该如何处理呢?
    • @MohitModi,如果您不想覆盖名称,请不要设置它。将其保留在 DB 中,不要从 companyMaster.Name 中设置 company.Name
    • 但如果我没有在 Action Bind 列表中设置 CompanyName。然后它向我显示错误消息“一个或多个实体的验证失败。有关更多详细信息,请参阅“EntityValidationErrors”属性。我不希望用户可以更改公司名称,所以我没有将该字段包含在绑定列表中。 bcz 如果我在绑定参数中设置,任何 bady 都可以通过 ajax 调用更改 CompanyName。
    • @MohitModi,您可以将其保留在 Action Bind 列表中 - 只是不要在代码中使用它 - 即此行不应出现 company.Name= companyMaster.Name;,您可以将 ModelState.Remove("Name"); 删除为好
    • 但 CompanyMaster.Name 字段在模型上有必填字段验证。那我该如何处理这种情况
    猜你喜欢
    • 1970-01-01
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多