我在我的MVC 3应用程序中使用实体框架4.3,在尝试更新实体时(创建和删除工作正常)我收到此错误:
存储更新,插入或删除语句会影响意外的行数(0)
当我进入调试模式时,我在[HttpPost]方法上看到没有提供Feed ID:
public ActionResult Edit(Feed feed)
{
if (ModelState.IsValid)
{
db.Entry(feed).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.FolderId = new SelectList(db.Folders, "FolderId", "Name", feed.FolderId);
return View(feed);
}
虽然在正常的Get方法中传递了id。那些是我的实体
饲料:
public class Feed
{
[ScaffoldColumn(false)]
public int FeedId { get; set; }
[StringLength(150, ErrorMessage = "The {0} must be less then {1} charecters")]
public string Title { get; set; }
[ScaffoldColumn(false)]
public string Description { get; set; }
[Required(ErrorMessage = "you must enter a valid link")]
[StringLength(500, ErrorMessage = "The {0} must be less then {1} characters long.")]
public string LinkUrl { get; set; }
[ScaffoldColumn(false)]
public DateTime PublishDate { get; set; }
[ScaffoldColumn(false)]
public string Image { get; set; }
[ForeignKey("Folder")]
[Required(ErrorMessage="you must choose a folder")]
public int FolderId { get; set; }
public virtual Folder Folder { get; set; }
public Feed()
{
PublishDate = new DateTime(2012, 1, 1);
}
}
文件夹:
public class Folder
{
public int FolderId { get; set; }
[Required(ErrorMessage = "you must enter a folder name")]
[StringLength(150, ErrorMessage = "the {0} must be less then {1} charecters")]
public string Name { get; set; }
}
我已经找到了一个解决方案,但没有一个能够工作,就像尝试刷新方法一样,DbContext中不存在或在FeedId和FolderId上定义[Key]属性。
答案 0 :(得分:0)
您不应手动维护实体状态 - 更改跟踪应由上下文执行。
您正在使用视图模型并假设它应该附加到数据库。
您需要执行类似..,
的操作Feed DbFeed = DBSet.Where(f => f.id = feed.Id);
DbFeed.Property = NewValue;
db.SaveChanges();
(原谅可能是错误的语法 - 默认情况下我在VB中工作)
也就是说,从DB Context获取Feed对象的新实例,然后对您给出的对象执行更改。
这是因为上下文实际上并没有给你一个简单的Feed
对象,而是一个包装它并具有相同属性的匿名类型。包装器会覆盖您的方法并检测属性更改,这是它维护状态的方式。
从视图中返回的Feed对象不包含此包装,因此存在问题
答案 1 :(得分:0)
实体框架跟踪对象,您从视图中获取的Feed未跟踪。这种情况的模式是从数据库中获取要更新的对象,然后调用UpdateModel,它将从未跟踪的实体应用更改到您跟踪的实体,然后您可以保存...
if (ModelState.IsValid)
{
var trackedEntity = db.Find(feed.Id)
UpdateModel(trackedEntity);
db.SaveChanges();
return RedirectToAction("Index");
}
答案 2 :(得分:0)
但是在我的模型中放置[ScaffoldColumn(false)]属性并没有在我的视图中创建它,并且没有传递id。
我将@Html.HiddenFor(model => model.FeedId)
添加到我的模型中,并解决了这个问题。
答案 3 :(得分:0)
显然你遇到了并发问题。 您的更新状态应该以:
运行 UPDATE tableA SET colA = 'value' WHERE colX1 = 'compare1' AND colX2 = 'compare2';
此colXn
可能是您的主键等,也可能是您正在使用的每个列。如果您没有处理并发,如果有人在您获取数据的同时,在您之前更改并保存数据,则WHERE
语句将永远不会匹配,因为您正在更新的记录信息已经包含新信息。 / p>