使用实体框架检测相关表中的更改和操作适当的插入和删除

时间:2010-05-26 12:47:29

标签: c# linq entity-framework-4

假设我有一个Person表,一个Role表,其中trel表PersonRoles将它们与多个表连接起来。

我创建了一个新人,并将他们分配给2个角色(角色1,角色3)。

然后我想编辑这个人;所以我检索他们的数据并将他们的角色绑定到一个复选框。我更改了值(取消选择角色1并选择角色2)然后我通过viewmodel发回这些数据。

然后我可以让实体框架为我更新这些角色,如删除PersonRoles中的条目到角色1,然后添加一个新条目作为角色2?或者我必须自己做这个逻辑吗?

类似** 这个 **我希望但显然不起作用。

[HttpPost]
    public ActionResult Edit(int id, PersonViewModel model)
    {
        if (ModelState.IsValid)
        {
            var person= GetPerson(id);
            person.Name= model.Name;
            person.Age = model.Age;

           ICollection<Roles> personroles = new Collection<Roles>();
            foreach (string rId in model.Roles)
            {
                personroles.Add(this.RoleRepository.Single(r => r.Id.ToString() == rId));
            }

            **person.Roles = personroles;**

            this.PersonRepository.SaveChanges();
            return RedirectToIndex(personId);
        }

        return View();
    }

干杯, 钢钣

1 个答案:

答案 0 :(得分:2)

魔鬼在细节中,你不给予任何,但一般来说,是的,EF可以做到这一点。

最好的方法是让PersonRoles只有两列:FK到PersonRole,两者都有级联删除,并使PK成为两者的复合键。如果您没有其他列,则EF会将此表包含在多对多关系中,这种关系将按照您期望的方式运行。

更新:由于您现在已经添加了源代码,让我们修复它(未经测试;这不在我的脑海中):

    if (ModelState.IsValid)
    {
        var person= GetPerson(id);
        person.Name= model.Name;
        person.Age = model.Age;

        var rolesToAdd = model.Roles.Where(mr => !person.Roles.Any(pr => pr.Id == mr);
        var rolesToRemove = person.Roles.Where(pr => !model.Roles.Any(mr => pr.Id == mr);

        foreach (string rId in rolesToAdd)
        {
            person.Roles.Add(this.RoleRepository.Single(r => r.Id.ToString() == rId));
        }
        foreach (string rrId in rolesToRemove)
        {
            var remove = person.Roles.Where(r => r.Id == rrId).Single();
            person.Roles.Remove(remove);
        }

        this.PersonRepository.SaveChanges();
        return RedirectToIndex(personId);
    }