【问题标题】:Updating many-to-many join table incorrectly错误地更新多对多连接表
【发布时间】:2013-04-07 04:50:53
【问题描述】:

我有一个 ChangeRequest 对象和一个具有多对多关系的 BusinessArea 对象。有一个连接表:ChangeRequestBusinessArea。

如果我使用 BusinessAreaID 2、7、8 和 10 创建并保存新的 ChangeRequest,则连接表会更新得很好。

例如

ChangeRequestID BusinessAreaID
1               2
1               7
1               8
1               10

但是,当我随后编辑并保存 BusinessAreaID 为 1、2、3、7 和 10 的相同 ChangeRequest 时,我得到以下信息:

ChangeRequestID BusinessAreaID
1               2
1               7
1               8
1               10
1               11
1               12
1               13
1               14
1               15

代码如下:

namespace MOC.Models
{
public class ChangeRequest
{
    public ChangeRequest()
    {
        BusinessAreas = new List<BusinessArea>();
    }

    public int ChangeRequestID { get; set; }
    public string ChangeRequestName { get; set; }

    public virtual ICollection<BusinessArea> BusinessAreas { get; set; }
}
}

namespace MOC.Models
{
public class BusinessArea
{
    public int BusinessAreaID { get; set; }
    public string BusinessAreaName { get; set; }

    public virtual ICollection<ChangeRequest> ChangeRequests { get; set; }
}
}

动作方法

[HttpPost]
public ActionResult Edit(int id, ChangeRequestViewModel ChangeRequestViewModel)
{
    if (ModelState.IsValid)
    {
        var changeRequest = new ChangeRequest
        {
            ChangeRequestID = id
        };

        AddOrUpdateBusinessAreas(changeRequest, ChangeRequestViewModel.BusinessAreas);
        db.Entry(changeRequest).State = EntityState.Modified;
        db.SaveChangeRequests();

        return RedirectToAction("Index");
        }
        return View(ChangeRequestViewModel);
    }

    private void AddOrUpdateBusinessAreas(ChangeRequest ChangeRequest, IEnumerable<AssignedBusinessAreaData> assignedBusinessAreas)
    {
        foreach (var assignedBusinessArea in assignedBusinessAreas)
        {
            if (assignedBusArea.Assigned) {
                var busarea = new BusArea { BusAreaID = assignedBusArea.BusAreaID };
                Change.BusAreas.Add(busarea);
            } else {
                var busarea = new BusArea { BusAreaID = assignedBusArea.BusAreaID };
                Change.BusAreas.Remove(busarea);
            }
        }
    }

【问题讨论】:

    标签: c# asp.net-mvc entity-framework ef-code-first many-to-many


    【解决方案1】:

    您必须从数据库中加载ChangeRequest包括当前与其相关的BusinessAreas,以便能够删除关系。

    我假设ChangeRequestViewModel.AssignedBusinessAreaData 包含带有标志Assigned 的所有可能区域,如果该区域是否必须分配给ChangeRequest。那么您的操作方法可能类似于以下内容:

    [HttpPost]
    public ActionResult Edit(int id, ChangeRequestViewModel ChangeRequestViewModel)
    {
        if (ModelState.IsValid)
        {
            var changeRequest = db.ChangeRequests
                .Include(c => c.BusinessAreas) // Important !
                .Single(c => c.ChangeRequestID == id);
    
            foreach (var assignedBusArea in ChangeRequestViewModel.BusinessAreas)
            {
                if (assignedBusArea.Assigned)
                {
                    if (!changeRequest.BusinessAreas
                        .Any(b => b.BusinessAreaID == assignedBusArea.BusAreaID))
                    {
                        var busArea = new BusinessArea
                        {
                            BusAreaID = assignedBusArea.BusAreaID
                        };
                        db.BusinessAreas.Attach(busArea);
                        // Attach is important to avoid duplication of the area
                        changeRequest.BusinessAreas.Add(busArea);
                    }
                    // else do nothing if the assigned area
                    // already belongs to the changeRequest
                }
                else
                {
                    var busArea = changeRequest.BusinessAreas.SingleOrDefault(
                        b => b.BusinessAreaID == assignedBusArea.BusAreaID);
                    if (busArea != null)
                        changeRequest.BusinessAreas.Remove(busArea);
                    // else do nothing if the unassigned area
                    // does not belong to the changeRequest anyway
                }
            }
            db.SaveChanges();
    
            return RedirectToAction("Index");
        }            
    
        return View(ChangeRequestViewModel);
    }
    

    【讨论】:

    • 完美。 :) 非常感谢。
    猜你喜欢
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 2015-05-28
    • 2015-08-06
    • 2012-04-08
    • 1970-01-01
    相关资源
    最近更新 更多