LINQ-to-SQL + One-to-many + DataBinding löschen
Verwende ich LINQ-to-SQL-zum laden von Daten aus einer Datenbank, die zwei Tabellen in einer eins-zu-viele-Beziehung (ein Rezept hat viele Zutaten).
Lade ich ein Rezept und LINQ ruft Zutat Objekte in ein EntitySet, die gebundenen in eine ListBox.
Wenn ich löschen möchte einige Zutaten aus einem Rezept, bekomme ich eine "Ein Versuch wurde gemacht, um zu entfernen, eine Beziehung zwischen einem Rezept und eine Zutat. Jedoch die Beziehung Fremdschlüssel (Inhaltsstoff.RecipeID) nicht auf null gesetzt werden.
Ich LÖSTE dieses problem mithilfe der bekannten Lösung durch das hinzufügen von 'DeleteOnNull="true"' auf die DBML-Datei. Aber das hinzufügen dieser Einstellung werden nur das problem, wenn wir uns beim löschen Zutat Objekte, die abgerufen wurden von der DB.
Das problem ist mit dem Wirkstoff Objekte, die erstellt wurden, in code (Hinzugefügt, um ein Rezept) und Hinzugefügt, um das EntitySet-Sammlung von Zutaten und dann gelöscht, BEVOR SubmitUpdates genannt wird. Dann wird die gleiche exception wieder passiert. Dies geschieht in der Regel auf ein neues, noch nicht gespeichertes Rezept wenn der Benutzer das hinzufügen von Zutaten hinzu, macht einen Fehler und löscht eine Zutat aus einem Rezept. Ich fügte hinzu, die DeleteOnNull sowohl 'Association Name="Recipe_Ingredient"' - Zeilen in der DBML.
Wie soll ich die entfernen Sie solche Objekte? Die einzige Lösung sehe ich im moment ist, dass ich laden Sie die Zutaten in eine Sammlung, die nicht unter den DataContext und dann beim speichern, löschen, alle Zutaten aus einem Rezept und fügen Sie dann wieder aus diesem cache..
- Sprechen Sie Linq-SQl oder Linq to Entities??
- Wird Ihre neue Reciepe Objekt gehören ein DataContext beim hinzufügen/löschen Zutat Objekte?
- Nein (wenn das Rezept ist neu) und ja (wenn es eine vorhandene, abgerufen fron DB und mit Zutaten Hinzugefügt werden).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es scheint, dass Sie sind auf der Suche nach etwas, das ich suchte mir einfach ein paar Tagen wieder, wenn ich fragte "Wie kann ich design sichern Datentypen für eine Datenbindung in WPF-dialog mit Ok/Abbrechen-Schaltflächen?".
Die Antwort ist eine faszinierende post von Paul Stovell beschreiben ein Beispiel IEditable adapter für Linq to Sql. Dies wird Ihnen ermöglichen, Ihre gewünschte "Apply/Cancel" - Semantik, die in einer generalisierten Weise, ohne Sie komplett distanziert sich von den darunter liegenden ORm-Klassen, generiert durch einen full-custom-SCHRIFTLICHEN Ebene.
Es ist ein ziemlich guter trick, insgesamt, dass im wesentlichen lassen Sie umgehen die Probleme, die Sie kämpfen jetzt. 🙂
Auf einer anderen Anmerkung, ich bin neugierig, warum Ihr Rezept-Wirkstoff-Beziehung ist 1:n statt m:n ist. Ist es der Einfachheit halber? Ich benutze Knoblauch in eine Menge Rezepte. 🙂
Erklärung des Problems: Beide Entitäten, c und ce, sind nicht in Bezug auf eine Daten-Kontext - Sie werden nicht verfolgt wird. EntitySet.Entfernen() (erste Zeile löschen) nur entfernt die Beziehung zwischen c und ce. Während c existieren kann ohne zugehörige Warenkorb-Einträge, ce kann nicht existieren ohne ein assiciated Wagen, da eine foreign key-Einschränkung. Bei der Einreichung von änderungen an der Datenbank, die getrennt ce behandelt wird, als auch, was zu einer constraint-Verletzung und die Ausnahme.
Um loszuwerden, die unberührte und getrennt Warenkorb-Eintrag müssen Sie es auf Ihre Daten Kontext (wodurch es zu nachverfolgt werden) und dann markiere es zum löschen auf "Absenden". Der moment, den Sie Einreichen, werden Ihre änderungen den Warenkorb Eintrag wird korrekt gelöscht und nicht die Ursache der Ausnahme.
Für mehr details über das Problem, check this out:
http://msdn.microsoft.com/en-us/library/bb546187%28v=VS.100%29.aspx
müssen Sie entkoppeln die save-code von den Ereignissen, die in Ihrer GUI, wie es scheint, bist du ein wenig zu eifrig, zu speichern, Dinge in die db, bevor sich der Staub gelegt hat und Sie sind Warteschlangen und das entfernen von Sachen aus der db, der nie da ist an Erster Stelle, es wäre am besten, wenn Sie sich identifizieren konnten, einen Punkt, wenn der Benutzer wird "commit" Ihre änderungen, und in diesem moment verarbeiten-voll-Zustand der GUI - dadurch sparen Sie einen Haufen spaghetti-code.
Ich würde auch neugierig sein, zu wissen, wenn Ihre Entitäten haben AutoWert-IDs oder wenn Sie einige andere-ID-Mechanismus. Du bist wahrscheinlich dem senden Gelöscht, um die Datenbank für die noch kein commit ausgeführt wurde Bestandteil von Datensätzen, wenn diese NULL-IDs, ich denke, dass die linq-könnte man böse.
Haben Sie hook up einen textwriter zum DataContext.Anmelden, um zu sehen, welche Arten von SQL generiert wird, nur bevor Sie Ihr exeception?
Danke für deine Antwort, ich werde prüfen, die Beiträge und sehen, was ich tun kann. Ich muss sagen, ich bin überrascht zu sehen auch dieses problem Auftritt, scheint es ganz natürlich für mich, dass man Datensätze hinzufügen, um die LINQ-vorausgesetzt, "cache" der Daten, dann entscheiden sich löschen, einige von Ihnen und dann commit. Change tracking sollte in der Lage sein, damit umzugehen. Ich habe gerade angefangen mit LINQ, also kann ich tun, ein blöder Fehler irgendwo im code (wäre nicht der erste).
Auf dem anderen Hinweis: Sie haben ganz Recht, dass Knoblauch kann gehören viele Rezepte (nicht meine Cocktail-Rezepte gedacht!). Ich habe tatsächlich das Modell, dass mit einem Artikel-Objekt/Tabelle. Aber für ein Rezept, die Sie benötigen Mengen. Also in meinem Modell, haben Sie ein Rezept, dass 1:n Zutaten, die jeweils eine Menge, eine 1:1-link zu einem Artikel (der hat einen Namen, eine AlcoholContent und einige Daten zu etablieren, die eine Austauschbarkeit Hierarchie) und ein 1:1-Verbindung zu einem Gerät (für die Menge, um Sinn zu machen).
Also in einem Sinn, Inhaltsstoff-Tabelle ist eine M:N-Beziehung zwischen Rezept und Artikel, und zur gleichen Zeit, einige zusätzliche Informationen zu jedem einzelnen verbundenen Paares.
Ich hatte genau das gleiche problem. Ich hatte eine parent /child-Hierarchie, und beim hinzufügen und entfernen der untergeordneten Entität ohne zu speichern in die Datenbank, die ich erhielt, die "Ein Versuch wurde gemacht, um eine Beziehung entfernen" Ausnahme.
Entdeckte ich, dass dieses problem nur entstanden, wenn ich ein Objekt style-Eigenschaft des Kindes an einen anderen linq-sql-Entität vor dem speichern. zB
1. Dies schafft die Fehler
2. Dies schafft nicht den Fehler
Seltsam genug, der Fehler, der entsteht 1. gibt an, das problem ist mit der Beziehung auf die RetailAccountCustomerId Eigenschaft von RetailAccountCustomerCard. ES HAT NICHTS zu tun mit der Karte-Objekt Hinzugefügt habe. Es scheint, dass einfach die Einstellung alle Objekt-Eigenschaft der neuen Entität löst das problem.
NB. Beispiel 1 funktioniert gut in Bezug auf sparen, es verursacht nur ein problem, wenn die die neue Entität gelöscht wird, bevor Sie Sie speichern.
Habe ich ein ähnliches Problem, als workaround muss ich anrufen DataContext.GetChanges(), dann scheint alles zu haben, fing auf einmal 🙂
Einem anderen problem haben, könnten Sie es, dass Sie die Bindung zu Spalten und nicht-Entität-Eigenschaften, und damit die referenzielle Sammlungen werden nicht aktualisiert (schon erwähnt von jemand anderem, aber die Durchsetzung der Tat).