0

I am trying to add a record to a database from a ViewModel using ASP MVC. The code will allow only certain models to be added. Others throw the exception:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

View Model:

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;}
}

get Controller:

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

this Controller works:

[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");
}

this Controller does not:

[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();
}

this Controller does not:

[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///////
}

this Controller does not:

[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///////
}

this Controller does not:

[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///////
}

this Controller does not:

[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///////
    }
}

I also saw another Refresh method shown as db.Refresh but it is not available to me.

I have look into:

None of the links helped. I have tried adding hidden fields to my view like so.

@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);
}

Does anyone know how to fix this exception?

Community
  • 1
  • 1
samjk14
  • 3
  • 4
  • 1
    In your first "failed" example you are trying to insert an object before creating it first. Make sure you create "FamilyApp" before you add fields to it and before persisting it to the db. – Ricardo Sanchez Oct 02 '14 at 00:08
  • It is part of the view model the same as "Family." How would "Family" be instantiated but "FamilyApp" is not? And the object has values from the view (i.e. FamilyApp.NeedsReview is true). Also I have tried var app = new FamilyApp(); then set all variables manually. – samjk14 Oct 02 '14 at 00:15
  • Your code shows only the controller methods that process and save the data. Show us the view methods (the ones without [HttpPost]). How do you create the model object in the first place. – Santhos Oct 02 '14 at 00:16
  • Why do you call the SaveChanges method twice? The objects have relation, if you modify then at once and then call a single SaveChanges, it should work. Another problem is that you add the same object twice to the context, if you add object with relations, you dont need to call another db.FamilyApp.Add. The object was already added with the db.Family.Add. – Santhos Oct 02 '14 at 00:25
  • I was trying different things because from what I read this issue comes from the database and context being out of sync. But i am the only one using this for now. And I did not set relations in that example I tried to treat it as a separate entity (i.e. did not add app using model.Family.FamilyApps.Add(app) or db.Families.FamilyApps.Add(app) I used db.FamilyApps.Add(app)) – samjk14 Oct 02 '14 at 00:34
  • paste bin of view http://pastebin.com/xaNue9me – samjk14 Oct 02 '14 at 00:38
  • If there is a relation, then you simply cannot treat those objects separately...also why would you? It is quite simple to add the whole bunch of objects with one context Add. The context will then do the inserts for you anyway and in the right order, so you don't have to worry. I have to go to bed, I leave to work soon. Contact me on my email if you need more help. – Santhos Oct 02 '14 at 00:43
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Oct 02 '14 at 02:04

2 Answers2

0

I believe the right method you are looking for is something like this: (Please note, that I wrote this here on stackoverflow and did not run the code)

[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();
}

If I am correct, the Family and FamilyApp have one-to-one relation. You can easily create the whole object structure and then add the "root" object, or just one of the objects, and the others should be added, too.

Santhos
  • 3,348
  • 5
  • 30
  • 48
  • see new controller. I had to modify your slightly but still nothing – samjk14 Oct 02 '14 at 00:45
  • Not sure which one, anyway if there is an object in database then you cannot set ID and other values and then Add it to the context. You might be able to do it if you set its state to Modified, but I am not completely sure. It is better to load the object from database using e.g. Find method and then modify it and add it to the new Family class. You should simply read more about entity framework or do a proper database profiling to see where the error occurs. – Santhos Oct 02 '14 at 00:50
  • I have tried pulling the family record using find then adding the app from there. It gave the same error. forgot to put that in question. – samjk14 Oct 02 '14 at 00:54
0

I got this error by Updating EF Verion from 5 to 6 solved the issue.

Muhammad Aqib
  • 709
  • 7
  • 14