このチュートリアルに基づいて多対多の実装を作成しましたが、残念ながら、モデルに投稿された値を実際に保存することはできません。
[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();
これにより、現在のユーザーがコンテキストに関連付けられ、それに関連付けられているすべてのサイトがコンテキストに読み込まれ(投稿されているユーザーには実際にはその情報が含まれていないため)、すべてが機能します。
単一のオブジェクトに対してすべてのデータを投稿するのがおそらくベストプラクティスですが、その方法がわかりません。