0

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

1 回答 1

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;      
        //...
    }
}
于 2013-10-07T05:11:24.050 回答