【问题标题】:"Store update, insert, or delete statement affected an unexpected number of rows (0)."“存储更新、插入或删除语句影响了意外的行数 (0)。”
【发布时间】:2014-10-01 23:44:26
【问题描述】:

我正在尝试使用 ASP MVC 从 ViewModel 向数据库添加记录。该代码将只允许添加某些模型。其他人抛出异常:

存储更新、插入或删除语句影响了意外数量的行 (0)。 自加载实体后,实体可能已被修改或删除。 刷新 ObjectStateManager 条目。

查看模型:

public class FamilyApplicationViewModel
{
    public FamilyApplicationViewModel()
    {

    }
    public int ID { get; set; }
    public Family Family { get; set; }
    public FamilyApp FamilyApp { get; set; }
    public List<FamilyIncome> FamilyIncomes { get; set; }
    public List<FamilyMember> FamilyMembers { get; set;}
}

获取控制器:

    public ActionResult Create()
    {
        return View();
    }

这个控制器工作:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FamilyApplicationViewModel model)
{
    var user = "Sam";
    model.Family.CreatedBy = user;
    model.Family.ModifiedBy = user;
    //all other props set in view

    var fam = db.Families.Add(model.Family);

    db.SaveChanges();
    return RedirectToAction("Index");
}

这个控制器没有:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FamilyApplicationViewModel model)
{
    var user = "Sam";
    model.Family.CreatedBy = user;
    model.Family.ModifiedBy = user;

    var app = new FamilyApp();

    app.AppYear = DateTime.Now.Year;
    app.ModifiedBy = user;
    app.CreatedBy = user;
    // other family app props set

    model.Family.FamilyApps.Add(app);

    db.Families.Add(model.Family);
    db.SaveChanges();
}

这个控制器没有:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FamilyApplicationViewModel model)
{
    var user = "Sam";
    model.Family.CreatedBy = user;
    model.Family.ModifiedBy = user;

    var fam = db.Families.Add(model.Family);

    db.SaveChanges();

    model.FamilyApp.AppYear = DateTime.Now.Year;
    model.FamilyApp.ModifiedBy = user;
    model.FamilyApp.CreatedBy = user;

    var app = model.FamilyApp;

    model.FamilyApp.FamilyId = fam.FamilyId;

    db.FamilyApps.Add(app);
    db.SaveChanges(); ///////Exception Here///////
}

这个控制器没有:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FamilyApplicationViewModel model)
{
    var user = "Sam";
    model.Family.CreatedBy = user;
    model.Family.ModifiedBy = user;

    model.FamilyApp.AppYear = DateTime.Now.Year;
    model.FamilyApp.ModifiedBy = user;
    model.FamilyApp.CreatedBy = user;

    var app = model.FamilyApp;

    model.Family.FamilyApps.Add(app);
    db.Families.Add(model.Family);
    db.SaveChanges(); ///////Exception Here///////
}

这个控制器没有:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FamilyApplicationViewModel model)
{
    var user = "Sam";

    model.FamilyApp.AppYear = DateTime.Now.Year;
    model.FamilyApp.ModifiedBy = user;
    model.FamilyApp.CreatedBy = user;
    model.FamilyApp.FamilyId = 1; //this does exist in db

    db.FamilyApps.Add(model.FamilyApp);
    db.SaveChanges(); ///////Exception Here///////
}

这个控制器没有:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FamilyApplicationViewModel model)
{
    var user = "Sam";

    model.FamilyApp.AppYear = DateTime.Now.Year;
    model.FamilyApp.ModifiedBy = user;
    model.FamilyApp.CreatedBy = user;
    model.FamilyApp.FamilyId = 1; //this does exist in db

    db.FamilyApps.Add(model.FamilyApp);

    try
    {
        db.SaveChanges();
    }
    catch
    {
        ((IObjectContextAdapter)db).ObjectContext.Refresh(RefreshMode.ClientWins, db.Families);
        ((IObjectContextAdapter)db).ObjectContext.Refresh(RefreshMode.ClientWins, db.FamilyApps);
        db.SaveChanges(); ///////Exception Here///////
    }
}

我还看到了另一种 Refresh 方法,显示为 db.Refresh,但我无法使用它。

我已经调查过:

这些链接都没有帮助。我试过像这样在我的视图中添加隐藏字段。

@Html.HiddenFor(m => m.ID);
@Html.HiddenFor(m => m.Family.FamilyId);
@Html.HiddenFor(m => m.FamilyApp.FamilyAppId);
@for (int i = 0; i < 10; i++)
{
    @Html.HiddenFor(m => m.FamilyIncomes[i].FamilyIncomeId);
    @Html.HiddenFor(m => m.FamilyMembers[i].FamilyMemberId);
}

有人知道如何解决这个异常吗?

【问题讨论】:

  • 在您的第一个“失败”示例中,您尝试先插入一个对象,然后再创建它。确保在向其添加字段之前创建“FamilyApp”并将其持久化到数据库之前。
  • 它是视图模型的一部分,与“家庭”相同。如何实例化“Family”而“FamilyApp”不是?并且该对象具有来自视图的值(即 FamilyApp.NeedsReview 为真)。我也试过 var app = new FamilyApp();然后手动设置所有变量。
  • 您的代码仅显示处理和保存数据的控制器方法。向我们展示视图方法(没有 [HttpPost] 的方法)。首先如何创建模型对象。
  • 为什么要调用两次 SaveChanges 方法?对象有关系,如果您立即修改然后调用单个 SaveChanges,它应该可以工作。另一个问题是您将相同的对象添加到上下文中两次,如果您添加具有关系的对象,则不需要调用另一个 db.FamilyApp.Add。该对象已通过 db.Family.Add 添加。
  • 我正在尝试不同的事情,因为从我读到的内容来看,这个问题来自数据库和上下文不同步。但我是目前唯一使用这个的人。而且我没有在该示例中设置关系,我试图将其视为一个单独的实体(即没有使用 model.Family.FamilyApps.Add(app) 或 db.Families.FamilyApps.Add(app) 添加应用程序我使用了 db.Family.FamilyApps.Add(app) 或 db.Families.FamilyApps.Add(app)。 FamilyApps.Add(app))

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


【解决方案1】:

我相信您正在寻找的正确方法是这样的: (请注意,这是我在 stackoverflow 上写的,并没有运行代码)

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FamilyApplicationViewModel model)
{
    var user = "Sam";
    model.Family.CreatedBy = user;
    model.Family.ModifiedBy = user;

    model.Family.FamilyApp = new FamilyApp();        

    model.Family.FamilyApp.AppYear = DateTime.Now.Year;
    model.Family.FamilyApp.ModifiedBy = user;
    model.Family.FamilyApp.CreatedBy = user;

    db.Family.Add(model.Family);
    db.SaveChanges();
}

如果我是正确的,Family 和 FamilyApp 是一对一的关系。您可以轻松创建整个对象结构,然后添加“根”对象,或仅添加其中一个对象,其他对象也应添加。

【讨论】:

  • 查看新控制器。我不得不稍微修改你的,但仍然没有
  • 不确定是哪一个,无论如何如果数据库中有一个对象,那么您无法设置 ID 和其他值,然后将其添加到上下文中。如果您将其状态设置为已修改,您也许可以做到这一点,但我不完全确定。最好使用例如从数据库加载对象找到方法,然后对其进行修改并将其添加到新的 Family 类中。您应该简单地阅读有关实体框架的更多信息或进行适当的数据库分析以查看错误发生的位置。
  • 我尝试使用 find 提取家庭记录,然后从那里添加应用程序。它给出了同样的错误。忘记提出问题了。
【解决方案2】:

我通过将 EF Verion 从 5 更新到 6 解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    相关资源
    最近更新 更多