2012-03-28 8 views
1

Ich brauche Bestätigung meines Ansatzes dafür, ich verwende EF und ASP.NET MVC und ich versuche, Entitäten auf der Grundlage der Benutzerauswahl (d. h. basierend auf dem, was sie aktiviert/deaktiviert haben) zu entfernen.Ich empfange "Sammlung wurde geändert; Aufzählungsoperation wird möglicherweise nicht ausgeführt." Während Foreach

Um dies zu tun, schaue ich auf die IDs, die aus dem Formular aus den Kontrollkästchen, übereinstimmenden, was ich in der Datenbank habe und dann zuerst alle neuen hinzufügen und dann alle entfernen, die nicht übereinstimmen.

Es folgt der Code, den ich ursprünglich hatte: „Die Auflistung wurde geändert; Enumerationsvorgang nicht ausführen kann“

 [HttpPost] 
    public ActionResult Edit(int id, FormCollection collection, VMinstanceRole vmodel) 
    { 
     try 
     { 
      var instancerole = db.instanceRoles.Find(id); 

      if (ModelState.IsValid) 
      { 
       UpdateModel<instanceRole>(instancerole, "instanceRole"); 
       var keys = instancerole.rights.Select(c => c.Id); 

       foreach (var pid in vmodel.selectedId.Except(keys)) 
       { 
        var right = new right { Id = pid }; 
        db.rights.Attach(right); 
        instancerole.rights.Add(right); 
       } 

       foreach (var pid in keys.Except(vmodel.selectedId)) 
       { 
        var right = instancerole.rights.Where(c => c.Id == pid).Single(); 
        instancerole.rights.Remove(right); 
       } 


       db.SaveChanges(); 
      } 

      // TODO: Add update logic here 

      return RedirectToAction("Index"); 
     } 
     catch (InvalidCastException e) 
     { 
      return View(); 
     } 
    } 

jedoch wurde vorgestellt, der folgende Fehler

Also, dies zu versuchen und zu lösen habe ich beschlossen, eine separate Liste zu halten und danach basierend auf teh Liste zu entfernen, den Fehler zu überwinden:

 [HttpPost] 
    public ActionResult Edit(int id, FormCollection collection, VMinstanceRole vmodel) 
    { 
     try 
     { 
      var instancerole = db.instanceRoles.Find(id); 
      List<right> removeList = new List<right>(); 
      if (ModelState.IsValid) 
      { 
       UpdateModel<instanceRole>(instancerole, "instanceRole"); 
       var keys = instancerole.rights.Select(c => c.Id); 

       foreach (var pid in vmodel.selectedId.Except(keys)) 
       { 
        var right = new right { Id = pid }; 
        db.rights.Attach(right); 
        instancerole.rights.Add(right); 
       } 

       foreach (var pid in keys.Except(vmodel.selectedId)) 
       { 
        var right = instancerole.rights.Where(c => c.Id == pid).Single(); 
        removeList.Add(right); 
       } 

       foreach (var right in removeList) 
       { 
        instancerole.rights.Remove(right); 
       } 
       db.SaveChanges(); 
      } 

      // TODO: Add update logic here 

      return RedirectToAction("Index"); 
     } 
     catch (InvalidCastException e) 
     { 
      return View(); 
     } 
    } 

Das aber scheint zu funktionieren, ich bin nicht sicher, ob Ich habe das Richtige getan. Hauptsächlich, weil ich eine andere Schleife mache. Gibt es einen besseren Weg, dies zu erreichen, oder ist das gut genug?

Antwort

0

Versuchen Sie folgendes:

foreach (var pid in keys.Except(vmodel.selectedId).ToList()) 
{ 
    var right = instancerole.rights.Where(c => c.Id == pid).Single(); 
    instancerole.rights.Remove(right); 
} 

Enumerator Sie in foreach-Schleife aufzählen wird bereits entsorgt vom Moment Sie Ihren ersten Artikel löschen.

+0

Hallo Ilya, danke für die Antwort Ich sehe was du meinst. Das fühlt sich viel besser an als das, was ich habe. Vielen Dank – user1012500

0

Der Grund für die nicht eine Sammlung bearbeiten zu können, wenn sie mit foreach Aufzählen hier allein dokumentiert gut genug ist (nur überprüfen Sie die ‚verwandten‘ Links auf der Seite), und Sie wissen, dass nicht tun, könnten Sie eine einfache for Schleife und ändern, um beim Entfernen eines Elements zu indizieren - das ermöglicht Ihnen, eine Schleife zu pflegen.

for (int i = 0; i < max; i++) { 
    //if removing an item 
    //manipulate the index as desired... 
    i--; 
} 
4

Sie haben eine Standardlösung gefunden. Die andere Lösung, die funktioniert, besteht darin, ToList für die LINQ-Operation aufzurufen, die Ihr Schlüsselobjekt erzeugt: Wenn Sie dies tun, trennt die Schlüssel aus der Sammlung von instances, wodurch beliebige unabhängige Änderungen an der ursprünglichen Sammlung möglich sind.

+0

hallo dasblinkenlight, thaks zum antworten Ich war ein wenig verwirrt, ob ich die ToList in einer anderen Variablen speichern sollte oder nicht, aber ich denke, ich habe es jetzt. Danke, dass du mir die Richtung aufgezeigt hast. – user1012500

Verwandte Themen