Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>After a lot of research I have understood that EF cannot update relationships - very surprising and disappointing. Aparently, the suggested solution is a manual update of the join table and navigation properties - not very good. NHibernate apparently does do this out of the box and I fully intend to investigate next time I need this.</p> <p>Luckily I came across a truly great solution from <a href="http://refactorthis.wordpress.com/2012/12/11/introducing-graphdiff-for-entity-framework-code-first-allowing-automated-updates-of-a-graph-of-detached-entities/" rel="nofollow">Refactor(This)</a> that adds an extension method to DbContext, allowing automated updating of complex relationships. There is even a Nuget package!</p> <p>So here is my full solution:</p> <p>I've added an integer list to the Regulator class, which gets the IDs of the selected Arenas. </p> <pre><code>Public Class Regulator Public Property Id As Integer Public Property Name As String Public Property ArenaIDs() As ICollection(Of Integer) Public Overridable Property Arenas() As ICollection(Of Arena) End Class </code></pre> <p>In the GET Edit action, this is taken care of and a MultiSelectList is created:</p> <pre><code>' GET: /Regulator/Edit/5 Function Edit(Optional ByVal id As Integer = Nothing) As ActionResult Dim regulator As Regulator = db.Regulators.Find(id) If IsNothing(regulator) Then Return HttpNotFound() End If For Each a In regulator.Arenas regulator.ArenaIDs.Add(a.Id) Next ViewBag.MultiSelectArenas = New MultiSelectList(db.Arenas.ToList(), "Id", "Name", regulator.ArenaIDs) Return View(regulator) End Function </code></pre> <p>And the MultiSelectList is used in the View:</p> <pre><code> &lt;div class="editor-field"&gt; @Html.ListBoxFor(Function(m) m.ArenaIDs, ViewBag.MultiSelectArenas) @Html.ValidationMessageFor(Function(model) model.Arenas) &lt;/div&gt; </code></pre> <p>In the POST Edit action the selection IDs are retrieved and used to update the Arenas collection. Then the magic comes in the with the UpdateGraph extension method that does what EF can not and updates the relationship!</p> <pre><code>' POST: /Regulator/Edit/5 &lt;HttpPost()&gt; _ &lt;ValidateAntiForgeryToken()&gt; _ Function Edit(ByVal regulator As Regulator) As ActionResult If ModelState.IsValid Then For Each i In regulator.ArenaIDs regulator.Arenas.Add(db.Arenas.Find(i)) Next db.UpdateGraph(Of Regulator)(regulator, Function(map) map.AssociatedCollection(Function(r) r.Arenas)) db.SaveChanges() Return RedirectToAction("Index") End If </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload