Question

I have a pair of ViewModels that references data from a number of tables. One for displaying and one for editing.

When I return data from the display ViewModel I can map all the relevant fields using ValueInjecter InjectFrom functionality.

What do I do next to get the database to update?

If I send the models to my Update method in the repository I can see the changes in the model but the context doesn't pick them up. Am I missing a step or is there a better way of doing this?

If I try to modify one table at a time I can get the context to pick up the changes but then get an error as follows:

Store update, insert, or delete statement affected an unexpected number of rows (0).

---EDIT---

I've updated the code and moved the mapping into the repository but I'm still getting the same error even though the debugger shows the entities with the new values.


ViewModels

public partial class HouseholdEditViewModel //for displaying in browser
{
    public int entityID { get; set; }
    public int familyID { get; set; }
    public string UPRN { get; set; }
    public string address { get; set; }
    public HousingTypeDropDownViewModel housingTypeID { get; set; }
    public KeyworkerDropDownViewModel keyworkerID { get; set; }
    public string startDate { get; set; }
    public bool loneParent { get; set; }
    public string familyPhoneCode { get; set; }
    public string familyPhone { get; set; }
}

public partial class HouseholdAddViewModel //for mapping to database
{
    public int familyID { get; set; }
    public string UPRN { get; set; }
    public string address { get; set; }
    public int entityTypeID { get; set; }
    public int housingTypeID { get; set; }
    public int keyworkerID { get; set; }
    public DateTime startDate { get; set; }
    public bool loneParent { get; set; }
    public string familyPhoneCode { get; set; }
    public string familyPhone { get; set; }
}

Repository (Current version - I've attempted a few different things without success)

public interface IHouseholdRepository : IDisposable
{
    //other methods here...

    void Update(HouseholdAddViewModel model, int id);
}


public void Update(HouseholdAddViewModel model, int id)
{
    //check address exists
    var address = (from u in context.tAddress
                  where model.UPRN.Contains(u.UPRN)
                  select u.UPRN);

    var ae = new tAddressEntity();
    ae.InjectFrom(model);
    ae.entityID = id;
    ae.UPRN = model.UPRN;

    context.tAddressEntity.Attach(ae);
    context.Entry(ae).State = EntityState.Modified;

    var e = new tEntity();
    e.InjectFrom(model);
    e.entityID = id;
    e.entityName = model.address;
    e.tAddressEntity.Add(ae);

    context.tEntity.Attach(e);
    context.Entry(e).State = EntityState.Modified;

    var a = new tAddress();
    a.InjectFrom(model);

    context.tAddress.Attach(a);
    context.Entry(a).State = address.ToString() == string.Empty ?
                            EntityState.Added :
                            EntityState.Modified;                     

    var hs = new tHousingStatus();
    hs.InjectFrom(model);
    hs.entityID = id;            

    context.tHousingStatus.Attach(hs);
    context.Entry(hs).State = EntityState.Modified;

    var k = new tKeyWorker();
    k.InjectFrom(model);
    k.entityID = id;

    context.tKeyWorker.Attach(k);
    context.Entry(k).State = EntityState.Modified;

    var l = new tLoneParent();
    l.InjectFrom(model);
    l.entityID = id;

    context.tLoneParent.Attach(l);
    context.Entry(l).State = EntityState.Modified;

    var h = new tHousehold();
    h.InjectFrom(model);
    h.entityID = id;
    h.tHousingStatus.Add(hs);
    h.tKeyWorker.Add(k);
    h.tLoneParent.Add(l);    

    context.Entry(h).State = EntityState.Modified;

    context.SaveChanges();
}

Controller

[HttpPost]
public ActionResult Edit(HouseholdAddViewModel model, int id)
{           
    model.entityTypeID = _repo.GetEntityType();

    if (ModelState.IsValid)
    {
        _repo.Update(model, id);
        return RedirectToAction("Index");

    }
    return View("Edit", id);
}
Était-ce utile?

La solution

The easiest way to update an entity using EF is to retrieve the entity (using it's key) and then apply the updates to that object instance. EF will automatically detect the updates to the entity and apply them when you call SaveChanges().

It seems as if you're creating new entities and you're not adding them to context so they aren't being picked up.

I would change your Edit controller to do this

[HttpPost]
public ActionResult Edit(HouseholdAddViewModel model, int id)
{
    model.entityTypeID = _repo.GetEntityType();

    if (ModelState.IsValid)
    {
        var h = _repo.GetHousehold(id);
        h.InjectFrom(model);
        h.entityID = id;      
        //...
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top