使用存储库更新 MVC 编辑操作中的多个表

本文关键字:操作 编辑 存储 更新 MVC | 更新日期: 2023-09-27 18:34:14

我有一对 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);
}

使用存储库更新 MVC 编辑操作中的多个表

使用

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