Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 尝试更新实体时出错_Asp.net Mvc_Entity Framework_Dbcontext - Fatal编程技术网

Asp.net mvc 尝试更新实体时出错

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

我在MVC 3应用程序中使用entity framework 4.3,当尝试更新实体(创建和删除操作正常)时,我遇到以下错误:

存储更新、插入或删除语句影响了意外的行数(0)

当我进入调试模式时,我看到在[HttpPost]方法上没有提供提要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 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';