【发布时间】:2014-11-21 18:17:53
【问题描述】:
我正在尝试编辑已添加的实体对象。
我用于实体框架的代码优先(或模型优先,无论你喜欢什么)的模型如下:
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 的脚手架为我创建的原始 Edit-savechanges。是这样的:
db.Entry(imageFile).State = EntityState.Modified;
db.SaveChanges();
两种解决方案均无效。第一个解决方案抛出一个InvalidOperationException:
附加信息:无法为属性“ImageUrl”调用成员“IsModified”,因为上下文中不存在“ImageFile”类型的实体。要将实体添加到上下文中,请调用 DbSet 的 Add 或 Attach 方法。
第二个解决方案也抛出一个InvalidOperationException:
附加信息:附加“BonTemps.Areas.Admin.Models.ImageFile”类型的实体失败,因为同一类型的另一个实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后将非新实体的状态设置为“未更改”或“已修改”。
我真的被困在这里,不知道我能做些什么来保存更改。为什么不保存?是不是和我在进入ActionResult方法后手动设置ImageUrl有关系?
我应该创建一个 ViewModel 并手动进行更改吗?有什么解决方案可以避免为此创建 ViewModel 吗?
【问题讨论】:
标签: c# asp.net-mvc entity-framework