Asp.net mvc 尝试更新实体时出错
我在MVC 3应用程序中使用entity framework 4.3,当尝试更新实体(创建和删除操作正常)时,我遇到以下错误: 存储更新、插入或删除语句影响了意外的行数(0) 当我进入调试模式时,我看到在[HttpPost]方法上没有提供提要Id:Asp.net mvc 尝试更新实体时出错,asp.net-mvc,entity-framework,dbcontext,Asp.net Mvc,Entity Framework,Dbcontext,我在MVC 3应用程序中使用entity framework 4.3,当尝试更新实体(创建和删除操作正常)时,我遇到以下错误: 存储更新、插入或删除语句影响了意外的行数(0) 当我进入调试模式时,我看到在[HttpPost]方法上没有提供提要Id: public ActionResult Edit(Feed feed) { if (ModelState.IsValid) { db.Entry(feed).State = Entity
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 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]属性 您不应该手动维护实体状态-更改跟踪应该由上下文执行 您使用的是视图模型,并假设它应该附加到数据库 你需要做一些事情,比如
Feed DbFeed = DBSet.Where(f => f.id = feed.Id);
DbFeed.Property = NewValue;
db.SaveChanges();
(请原谅可能不正确的语法-默认情况下我在VB中工作)
也就是说,从DB上下文中获取提要对象的新实例,然后对给定的对象执行更改
这是因为上下文实际上并没有给你一个普通的Feed
对象,而是一个匿名类型,它包装了它并具有相同的属性。包装器覆盖您的方法并检测属性更改,这是它维护状态的方式
您从视图返回的提要对象不包含此包装,因此问题在于实体框架跟踪对象,您从视图获得的提要未跟踪。这种情况的模式是从数据库中获取要更新的对象,然后调用UpdateModel,它将把未跟踪实体的更改应用到跟踪实体,然后保存
if (ModelState.IsValid)
{
var trackedEntity = db.Find(feed.Id)
UpdateModel(trackedEntity);
db.SaveChanges();
return RedirectToAction("Index");
}
显然,但是在我的模型中放置[ScaffoldColumn(false)]属性时,它没有在我的视图中创建它,并且没有传递id
我在我的模型中添加了
@Html.HiddenFor(model=>model.FeedId)
,解决了这个问题。显然您遇到了并发问题。
您的更新状态应运行为:
UPDATE tableA SET colA = 'value' WHERE colX1 = 'compare1' AND colX2 = 'compare2';
这个
colXn
可以是您的主键等,也可以是您正在使用的每一列。如果您不处理并发,如果有人与您同时获取数据,在您之前更改并保存数据,您的WHERE
语句将永远不会匹配,因为您正在更新的记录信息已经有了新信息。您的视图中是否有FeedId
?你们必须往返它的值,例如在隐藏字段中,才能在HTTP Post中得到它。谢谢,这是我的问题。我将@Html.HiddenFor(model=>model.FeedId)添加到我的View@Moran-你不应该试图管理自己的状态。。。这可能会导致问题,特别是当多线程(如MVC)或使用多个上下文时。对不起,我不确定我是否同意这一点。您进行数据库往返只是为了让EF开始跟踪具有该特定id的Feed
对象。您只需执行db.Feed.Attach(Feed)即可代码>然后db.Entry(feed.State=EntityState.Modified
UPDATE tableA SET colA = 'value' WHERE colX1 = 'compare1' AND colX2 = 'compare2';