【问题标题】:MVC 5 Edit Action Saving Input ErrorMVC 5 编辑操作保存输入错误
【发布时间】:2017-04-01 04:11:37
【问题描述】:

当我编辑“salesmember”并尝试保存新文件路径/或旧文件路径时,根据用户输入,它应该覆盖图像,或者它将使用存储在数据库。

但是,当我尝试修改实体状态时,在我将更改保存到我的 SQL Server 之前,我收到了错误:

EntityFramework.dll 中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理。附加信息:附加类型为“SalesMember”的实体失败,因为同一类型的另一个实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后将非新实体的状态设置为“未更改”或“已修改”。

我正在使用该主键修改 SalesMember。其中,它将图像保存在本地,但不会保存数据库行。

我的编辑操作 -----

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include="SalesMemberID,FirstName,LastName,PageName,CellPhone,Email,InactiveRedirectTo,CustomText,Photo,Active, Position")] SalesMember salesmember, HttpPostedFileBase file)
    {
        SalesMember SalesPhoto = db.SalesMembers.Find(salesmember.SalesMemberID);

        salesmember.Photo = saveImage(file, salesmember, SalesPhoto);


        if (ModelState.IsValid)
        {
            salesmember.AddDate = SalesPhoto.AddDate;
            salesmember.UpdateDate = DateTime.Now;
            salesmember.IPAddress = Request.UserHostAddress;
            salesmember.AddUser = "admin";
            salesmember.UpdateUser = "admin";

            db.Entry(salesmember).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(salesmember);
    }

SalesPhoto 保存功能 --

private string saveImage(HttpPostedFileBase file, SalesMember salesmember, SalesMember SalesPhoto = null)
    {
        string photo = "";
        string returnPhoto = "";

        //File blank
        if( file == null )
            //If File Path For that User Already In DB, return that File Path
            if(! String.IsNullOrEmpty(SalesPhoto.Photo))
                return "/Images/no-upload-icon.jpg"; 

        //If File ! empty, Save image uploaded

        photo = Server.MapPath("/Images/" + salesmember.PageName.ToString() + ".jpg");
        file.SaveAs(photo);
        returnPhoto = "/Images/" + salesmember.PageName.ToString() + ".jpg";

        return returnPhoto;
    }

我相信它与 LINQ 查询有关,因为当我删除 LINQ 查询和 saveImage 方法并使用测试路径(即“/Images/foo.jpg”)保存照片时,它可以工作。

提前致谢。

【问题讨论】:

    标签: c# asp.net-mvc entity-framework linq file-upload


    【解决方案1】:

    在实体框架的内存中不能有两个具有相同主键的实体(相同类型)。 salesmemberSalesPhoto 如果你想在你的表单中有AddDate 编辑,你可以将它作为HiddenField 包含在表单中,或者

    我的建议是在视图中处理 ViewModels 而不是 EF 模型 忽略这些问题

     [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include="SalesMemberID,FirstName,LastName,PageName,CellPhone,Email,InactiveRedirectTo,CustomText,Photo,Active, Position")] SalesMember salesmember, HttpPostedFileBase file)
    {
        SalesMember SalesPhoto = db.SalesMembers.AsNoTracking().Find(salesmember.SalesMemberID);
    
        salesmember.Photo = saveImage(file, salesmember, SalesPhoto);
    
    
        if (ModelState.IsValid)
        {
            salesmember.AddDate = SalesPhoto.AddDate;
            salesmember.UpdateDate = DateTime.Now;
            salesmember.IPAddress = Request.UserHostAddress;
            salesmember.AddUser = "admin";
            salesmember.UpdateUser = "admin";
    
            db.Entry(salesmember).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(salesmember);
    }
    

    【讨论】:

    • 如果我将视图中的值绑定到 salesmember,当我调用 db.SalesMembers.Find 并将返回的 salesmember 分配给“salesmember”时,不会覆盖之前在 salesmember 中绑定的所有值?
    • @DaveBoz 是的,它会(我理解错了),在表单帖子中包含您想要的所有内容作为 HiddenFileds,您会将点击保存到数据库或处理 ViewModels,您可以尝试其他东西(notracking ) 但不能 100% 确定它是否会起作用
    • @DaveBoz 你能试试AsNoTracking 告诉我它是如何工作的吗??
    • 我只是打算使用隐藏表单字段选项。但是 AsNoTracking?
    • 使用实体框架的黄金法则:never, never, never 保存同一个实体类的实例那张贴了。在最终保存该实例之前,始终从数据库中提取新的实体,并将发布的值映射到该实例。
    猜你喜欢
    • 2015-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 2016-12-19
    • 2022-01-08
    • 1970-01-01
    相关资源
    最近更新 更多