无法将实体对象保存到数据库

时间:2014-11-21 18:17:54

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

我正在尝试编辑已添加的实体对象。

我用于实体框架的代码首先(或模型优先,你喜欢什么)的模型如下:

public class ImageFile
{
    public int Id { get; set; }
    [DisplayName("Naam")]
    public string FileName { get; set; }

    public string ImageUrl { get; set; }
}

在视图中,我隐藏了ImageUrl并允许用户上传文件,该文件正常工作。在图像更改发生后(这是一个Edit方法),我想将对象保存回数据库。

以下方法演示:

public ActionResult Edit([Bind(Include = "Id,FileName,ImageUrl")] ImageFile imageFile, HttpPostedFileBase actualImage)
{
    if(actualImage != null && actualImage.ContentLength > 0)
    {
        ImageFile originalImageFile = db.Images.Find(imageFile.Id);
        if(originalImageFile.FileName != imageFile.FileName)
        {
            DeleteImage(originalImageFile.FileName);
        }
        string fullUrl = SaveImage(imageFile, actualImage);

        // Set the new imageUrl.
        imageFile.ImageUrl = fullUrl.Replace("~", "");

        // Save changes to database
        var entry = db.Entry(imageFile);
        entry.Property(i => i.ImageUrl).IsModified = true;
        entry.Property(i => i.FileName).IsModified = true;
        db.SaveChanges();

        return RedirectToAction("Index");
   }

   // Else that only changes the filename, instead of uploading a new file.
   // Uses same saving logic.

}

正如您所看到的,我已经从最初的编辑保存更改改变了MVC'脚手架为我创造。它类似于:

db.Entry(imageFile).State = EntityState.Modified;
db.SaveChanges();

这两种解决方案都不起作用。第一个解决方案抛出InvalidOperationException

  

其他信息:会员' IsModified'不能要求财产' ImageUrl'因为类型' ImageFile'的实体在上下文中不存在。要向上下文添加实体,请调用DbSet的Add或Attach方法。

第二个解决方案也会抛出InvalidOperationException

  

其他信息:附加类型为' BonTemps.Areas.Admin.Models.ImageFile'的实体。失败,因为同一类型的另一个实体已具有相同的主键值。使用'附加'方法或将实体的状态设置为“未更改”#39;或者'修改'如果图中的任何实体具有冲突的键值。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,请使用'添加'方法或“添加”#39;实体状态跟踪图形,然后将非新实体的状态设置为“未更改”。或者'修改'酌情。

我真的被困在这里,不知道我能做些什么来保存这些变化。为什么不能保存?在输入ActionResult方法后,是否与我手动设置ImageUrl有什么关系?

我应该创建一个ViewModel,并手动进行更改吗?有没有我可以避免为此创建ViewModel的解决方案?

1 个答案:

答案 0 :(得分:0)

不要试图告诉EF您已更改了属性,而是使用刚从数据库中提取的数据库实体。所以你拥有的地方

// Save changes to database
var entry = db.Entry(imageFile);
entry.Property(i => i.ImageUrl).IsModified = true;
entry.Property(i => i.FileName).IsModified = true;
db.SaveChanges();

会改为

// Save changes to database
originalImageFile.ImageUrl = imageFile.ImageURL;
originalImageFile.FileName = imageFile.FileName;
db.SaveChanges();