1

このチュートリアルに基づいて多対多の実装を作成しましたが、残念ながら、モデルに投稿された値を実際に保存することはできません。

[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()更新されません。

編集

私はいくつかのことに気づきました。1つは、関数内のサイトを反復処理するときに、サイトにUpdateUserSites例外をスローするいくつかのプロパティがありました。これは、既存のクエリセットを反復処理しながらクエリを実行することと関係がありました。私はこれをに変更context.Sitesすることで改善しましたcontext.Sites.ToList()

2つ目は、私の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に次の2行で関数を変更しました

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

これにより、現在のユーザーがコンテキストに関連付けられ、それに関連付けられているすべてのサイトがコンテキストに読み込まれ(投稿されているユーザーには実際にはその情報が含まれていないため)、すべてが機能します。

単一のオブジェクトに対してすべてのデータを投稿するのがおそらくベストプラクティスですが、その方法がわかりません。

4

1 に答える 1

0

ConnectionString アプリケーションをビルドするたびに mdf ファイルが上書きされる可能性が高いため、変更が永続化されていないと思われます。

于 2013-03-03T01:23:37.477 に答える