2 Stimmen

Kerndaten: Massenaktualisierungen möglich?

Ist es möglich, Massenaktualisierungen für eine bestimmte Entität in Core Data durchzuführen?

Kann ich bei einer Entität "Person" zum Beispiel so etwas tun?

Person.update(@"set displayOrder = displayOrder + 1 where displayOrder > 5")

Oder ist meine einzige Option, um alle Entitäten benötigt abrufen und dann Schleife durch und aktualisieren Sie einzeln?

Gracias

4voto

TechZen Punkte 64117

Sie denken an Core Data als SQL. Ein großer Fehler.

Entitäten sind keine Tabellen und Instanzen sind keine Datensätze. Jede Instanz ist ein eigenes Objekt, so dass Sie sie einzeln ändern müssen. Andernfalls hätte die Verwendung eines Objektgraphen keinen Sinn.

Bearbeiten01:

Wie würde dann Sie das folgende UI-Problem behandeln: Sie möchten eine Tabelle mit Personen Entitäten, geordnet nach "Name". ABER ... der Benutzer kann die angezeigten Personen Entitäten in dieser Tabelle neu anordnen UND Sie wollen, dass das persistiert wird, so dass die Entitäten jetzt nach "Name" sortiert sind + "displayOrder" (oder was immer Sie wollen nennen wollen). Wo pflegen Sie den Wert von "displayOrder", wenn nicht als Attribut der Entität Person?

Oh, ich verstehe, was du versuchst zu tun. Sie machen es viel schwieriger, als es sein muss. Core Data handhabt diese Art von Funktion problemlos.

Sortierreihenfolgen sind nicht (normalerweise, siehe unten ) Facetten des Datenmodells, sondern der View-Controller, d.h. es handelt sich lediglich um temporäre Aufträge, die dazu dienen, dem Benutzer Daten in sinnvoller Weise anzuzeigen. Als solche werden sie je nach Bedarf spontan erstellt. In diesem Fall würden Sie einen NSSortDescriptor/s erstellen, um nach den gewünschten Attributschlüsseln zu sortieren. Dann stellen Sie Ihre Fetch-Anfrage so ein, dass diese Sortierdeskriptoren verwendet werden. Dann würde Ihr Fetch ein Array mit den Elementen in der gewünschten Reihenfolge zurückgeben.

Kein Aufwand, kein Durcheinander.

Wenn der Benutzer eine andere Sortierreihenfolge wünscht, muss er nur eine andere Gruppe von Sortierbeschreibungen erstellen. Es gibt keinen Grund, die Sortierlogik in das eigentliche Datenmodell aufzunehmen, und es gibt viele Gründe, dies nicht zu tun.

Die Trennung der eigentlichen Daten von der Anzeige ist im Model-View-Controller-Entwurfsmuster, auf dem die gesamte iPhone-API basiert, sehr wichtig. Sie wollen keine Anzeigelogik in das Datenmodell einbinden und Sie wollen keine Daten speichern oder eine Datenverarbeitungslogik in der Anzeige haben.

Bearbeiten02:

In meinem Fall müssen die Benutzer in der Lage sein in die Anwendung zurückkehren, die Tabelle die Tabelle und die Entitäten der Person in der Reihenfolge zu sehen, in der THEY sie angelegt hat. Wie sonst können Sie dies tun, außer mit einem displayOrder-Attribut?

Wenn Sie den Auftrag als Benutzerdaten speichern wollen, müssen Sie ihn in das Datenmodell aufnehmen.

Zufälligerweise hatte ich gerade ein solches Bedürfnis. So habe ich das Problem für eine kleine Anzahl von Objekten gelöst. Dies sind die Methoden der Unterklasse NSMangedObject. Dies funktioniert für mehrere hundert leichtgewichtige Objekte.

Wenn Sie eine große Anzahl von schweren Objekten (Tausende) haben, schlage ich vor, eine leichtgewichtige Entität zu erstellen, um eine verknüpfte Liste zu implementieren. Nennen Sie es OrderEntity. Es hätte ein Index-Attribut, eine Beziehung zu der indizierten Entität, eine Beziehung zur vorherigen OrderEntity und eine Beziehung zur nächsten. (Die Verwendung einer leichtgewichtigen Entität verhindert, dass Sie schwere Objekte fehlerhaft machen müssen, was Speicher spart und alles schneller macht. Sie müssen das indizierte Objekt nur dann abfragen, wenn Sie es anzeigen müssen).

Dann verwenden Sie die Standardmethoden für verknüpfte Listen, um die Elemente in der Liste einzufügen, zu tauschen und zu verschieben. Dann rufen Sie update für die verschobenen Objekte auf und diese rufen alle nachfolgenden OrderEntities auf, um ihre Indizes zu aktualisieren.

Es kann so einfach sein wie eine Methode, die die nächste OrderEntity aufruft, den Index des aktuellen Objekts übergibt und die nächste OrderEntity anweist, ihre Reihenfolge auf passedIndex+1 zu setzen. Das ist im Grunde genau die Funktion der SQL-Anweisung, die Sie nachahmen wollen (denn die Logik ist natürlich dieselbe).

Wenn Sie dies häufig tun müssen, erstellen Sie eine NSManagedObject-Unterklasse, um die Indizierung zu handhaben, und lassen Sie dann Ihre indizierten Klassen davon erben.

1voto

Barry Wark Punkte 106328

Nein, Sie können in Core Data keine "Massenaktualisierungen" vornehmen. Wenn Sie glauben, dass Sie dies tun wollen, haben Sie den Sinn von Core Data nicht verstanden: Es ist no eine relationale Datenmaschine, sondern eine Rahmenmaschine für die Graphenverwaltung. Massenaktualisierungen, wie Sie sie beschreiben, sind das, was Sie mit Datentabellen machen. Das Iterieren durch einen Objektgraphen ist das, was man mit einer Objektgraphen-Verwaltungsmaschine macht.

Wenn Ihre Daten wirklich tabellarisch sind (was bei Ihnen der Fall sein könnte), sind Core Data möglicherweise nicht die beste Option. Das Problem der Massenaktualisierung war einer der Gründe, warum Brent Simmons weggeschaltet von Kerndaten für einige Anwendungen. Wie immer gilt: Verwenden Sie das richtige Werkzeug für die richtige Aufgabe.

In diesem Fall gibt es wahrscheinlich eine bessere Möglichkeit, das zu tun, was Sie wollen. Die Anzeigereihenfolge ist nicht wirklich eine Modelleigenschaft, sondern eher eine Ansichtseigenschaft. Wahrscheinlich möchten Sie eine abgeholte Eigenschaft erstellen, die nach etwas im Modell richtig sortiert. Wenn das ein Datum ist, haben Sie eine Datumseigenschaft. Wenn es sich um eine bevorzugte Anzeigereihenfolge handelt, sollten Sie die Elemente in einem Diagramm im Stil einer verknüpften Liste aufbewahren, in dem jede Instanz eine Vorher/Nachher-Beziehung hat. Die Aktualisierung dieser Liste ist einfach, und die Anzeige (eine sequenzielle Operation) ist ebenfalls einfach.

1voto

Der korrekte Weg wäre, ein Array aller Person-Objekte zurückzubekommen (stellen Sie einfach eine Abrufanforderung für alle Person-Entitäten ohne Angabe eines Prädikats).

Verwenden Sie dann die NSArray-Methode makeObjectsPerformSelector:withObject:, um eine Massenänderung vorzunehmen. Möglicherweise müssen Sie eine benutzerdefinierte Methode für das Objekt erstellen, damit es genau die gewünschte Änderung vornimmt.

Rufen Sie dann den Befehl save für Ihren NSManageObjectContext auf, und Ihre Änderungen werden gespeichert.

Wie bereits erwähnt, ist es nicht wie bei SQL, wo man Textaktualisierungen vornimmt - aber das bedeutet nicht, dass man nicht trotzdem Stapeländerungen vornehmen kann.

1voto

Dan Messing Punkte 798

Es ist nicht möglich, mit Core Data massenweise SQL-ähnliche Aktualisierungen vorzunehmen; Sie müssen eine Schleife durch alle Ihre Objekte ziehen, um die Werte zu aktualisieren.

Wenn Sie ein displayOrder-Attribut speichern möchten, müssen Sie es als Attribut im Datenmodell speichern. Dies ist ein so häufiges Problem, dass ich erstaunt bin, dass es dafür noch keine integrierte Lösung gibt.

0voto

Dave DeLong Punkte 240835

Dies ist nicht möglich, zumindest nicht, ohne die gesamte Core Data-Objekthierarchie zu umgehen (was wirklich nicht zu empfehlen ist).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X