将元素添加到列表而不是以多对多关系更新实体

时间:2013-03-03 01:16:26

标签: asp.net-mvc entity-framework

我写了一个基于this tutorial的多对多实现,遗憾的是我无法实际保存发布到我模型的任何值。

[HttpPost]
public ActionResult Edit(User user, string[] selectedSites)
{
    if (ModelState.IsValid)
    {
        UpdateUserSites(selectedSites, user);
        context.Entry(user).State = EntityState.Modified;
        context.SaveChanges();
        return RedirectToAction("Index");
    }
    ViewBag.PossiblePartners = context.Partners;
    ViewBag.Sites = PopulateSelectedSiteData(user);
    return View(user);
}

private void UpdateUserSites(string[] selectedSites, User userToUpdate)
{
    // if no sites are selected, give the user a fresh empty list of sites
    if (selectedSites == null)
    {
        userToUpdate.Sites = new List<Site>();
        return;
    }

    var newSelectedSites = new HashSet<string>(selectedSites);
    var existingUserSites = new HashSet<int>(userToUpdate.Sites.Select(site => site.Id));

    foreach (var site in context.Sites)
    {
        if (newSelectedSites.Contains(site.Id.ToString()))
        {
            if (!existingUserSites.Contains(site.Id))
            {
                // add a new site to the user
                userToUpdate.Sites.Add(site);
            }
        }
        else
        {
            if (existingUserSites.Contains(site.Id))
            {
                // remove an existing site from the user
                userToUpdate.Sites.Remove(site);
            }
        }
    }
}

UpdateuserSites函数肯定会在列表中添加元素,但在尝试使用context.SaveChanges()保存更改后,数据库不会更新。

修改

我注意到了一些事情。一,当我在我的UpdateUserSites函数中遍历站点时,该站点有一些属性会抛出异常。它有something to do with executing a query while iterating over an existing query set。我通过将context.Sites更改为context.Sites.ToList()

来解决此问题

两,我的Create函数运行正常。它添加了一个新用户,并毫不费力地为用户添加了一个站点。我添加的新条目以及现有条目对Sites属性的之外是可编辑的。

[HttpPost]
public ActionResult Create(User user, string[] selectedSites)
{
    if (ModelState.IsValid)
    {
        context.Users.Add(user);
        UpdateUserSites(selectedSites, user);
        context.SaveChanges();
        return RedirectToAction("Index");  
    }
    ViewBag.PossiblePartners = context.Partners;
    ViewBag.Sites = PopulateSelectedSiteData();
    return View(user);
}

修改2

这肯定与我的实体和当前的DbContext有关 - 我在context.Users.Attach(user);函数的if(ModelState.IsValid)内添加了Edit,现在我能够至少向用户添加网站。现在我无法删除它们。但至少我是在做点什么。

编辑3

我已将Edit恢复为原始状态,而是使用以下两行修改了我的UpdateUserSites函数

context.Users.Attach(userToUpdate);
context.Entry(userToUpdate).Collection(u => u.Sites).Load();

这将当前用户附加到上下文,将与其关联的所有站点加载到上下文中(因为发布的用户实际上并不包含该信息),然后一切正常!

最好的做法是针对单个对象发布所有数据,但我不知道该怎么做。

1 个答案:

答案 0 :(得分:0)

我认为您需要检查ConnectionString每次构建应用程序时,您的mdf文件可能会被覆盖,这就是为什么您认为您的更改未被保留的原因。