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

时间:2013-10-07 02:49:03

标签: c# asp.net-mvc viewmodel valueinjecter

我有一对ViewModel引用了许多表中的数据。一个用于显示,一个用于编辑。

当我从显示ViewModel返回数据时,我可以使用ValueInjecter InjectFrom功能映射所有相关字段。

接下来我该怎么做才能让数据库更新?

如果我将模型发送到存储库中的Update方法,我可以看到模型中的更改,但上下文不会提取它们。我错过了一步还是有更好的方法呢?

如果我一次尝试修改一个表,我可以获取上下文来获取更改但是会出现如下错误:

  

存储更新,插入或删除语句会影响意外   行数(0)。

--- --- EDIT

我已经更新了代码并将映射移动到了存储库中,但即使调试器显示具有新值的实体,我仍然会收到相同的错误。


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

存储库(当前版本 - 我尝试了一些不同的事情但没有成功)

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

1 个答案:

答案 0 :(得分:1)

使用EF更新实体的最简单方法是检索实体(使用 它的关键)然后将更新应用于该对象实例。当您致电SaveChanges()时,EF会自动检测实体的更新并应用它们。

好像你正在创建新的实体而你并没有将它们添加到上下文中 没有被接走。

我会更改您的编辑控制器来执行此操作

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