Обновите несколько таблиц в MVC Edit Action, используя репозиторий

У меня есть пара ViewModels, которые ссылаются на данные из нескольких таблиц. Один для отображения и один для редактирования.

Когда я возвращаю данные из отображения ViewModel, я могу отображать все соответствующие поля, используя функциональность ValueInjecter InjectFrom.

Что мне делать дальше, чтобы обновить базу данных?

Если я отправлю модели в свой метод Update в репозитории, я увижу изменения в модели, но контекст их не увидит. Я пропустил шаг или есть лучший способ сделать это?

Если я попытаюсь изменить одну таблицу за раз, я могу получить контекст для получения изменений, но затем получу следующую ошибку:

Оператор обновления, вставки или удаления хранилища затронул непредвиденное количество строк (0).

---РЕДАКТИРОВАТЬ---

Я обновил код и переместил сопоставление в репозиторий, но по-прежнему получаю ту же ошибку, хотя отладчик показывает объекты с новыми значениями.


Модели просмотра

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

Репозиторий (текущая версия — я безуспешно пробовал несколько разных способов)

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

Контроллер

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

person melkisadek    schedule 07.10.2013    source источник


Ответы (1)


Самый простой способ обновить объект с помощью EF — получить объект (используя его ключ), а затем применить обновления к этому экземпляру объекта. EF автоматически обнаружит обновления объекта и применит их при вызове SaveChanges().

Кажется, что вы создаете новые объекты и не добавляете их в контекст, поэтому они не подхватываются.

Я бы изменил ваш контроллер редактирования, чтобы сделать это

[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;      
        //...
    }
}
person hwiechers    schedule 07.10.2013
comment
Как мне затем сопоставить свойства с другими моделями? Я вижу правильные свойства, но не могу обновить таблицы реляционным способом. Например. entityName на tEntity будет обновляться, но AddressEntity не улавливает изменения... - person melkisadek; 07.10.2013