2009-03-10 22 views
3

Ich versuche, meine erste Cocoa-App zu schreiben, und Core Data macht es schwierig, meine Datenobjekte zu modellieren. Ich habe zwei Entitäten, die ich manipulieren möchte: Account und Transaction. Account hat einen lesbaren Namen und das ist es. Transaction speichert einen monetären Wert und verweist auf zwei Konten mit den Namen debitAccount und creditAccount (ich arbeite an einer Doppelbuch-Buchhaltungs-App).Erstellen einer Core Data Inverse-Beziehung

Ich möchte in der Lage sein, alle für einen Account gegeben, um die Transactions zu finden, ob sie debitAccount oder creditAccount verwenden. Wie kann ich das machen? Gibt es eine Möglichkeit, dies zu tun, die leicht mit Cocoa UI-Bindung funktioniert?

Antwort

0

Die Lösung, die am besten funktioniert (und machte die meisten Sinn) war für mich eine Unterklasse von NSManagedObject zu erstellen, wie meine Account Einheit zu verwenden:

@interface Account : NSManagedObject { 

} 
-(NSArray*)getTransactions; 
@end 

ich die tatsächliche Lookup Logik innerhalb -getTransactions haben, die wasn Es ist nicht so einfach mit der Hand zu machen. Dies funktioniert bisher gut, insbesondere weil der Methodenname KVO entspricht.

Um Core-Daten Account s anstelle von NSManagedObject s zurückgeben, musste ich die "Class" -Eigenschaft der Entität in Xcode Datenmodellierungstool ändern.

+0

Seien Sie vorsichtig. Der Grund für umgekehrte Beziehungen ist, dass sie dazu beitragen, die Konsistenz des Modells sicherzustellen. Wenn Sie ein Objekt löschen, das Ziel einer Beziehung ist und keine Inverse aufweist, müssen Sie sicherstellen, dass es aus dieser Beziehung entfernt wird, da andernfalls ungültige Referenzen entstehen. – Alex

+0

Diese Methode sollte nicht "-getTransactions" heißen, da sie keine Transaktionssammlung als Referenz zurückgibt. Verwenden Sie "-allTransactions" oder etwas Ähnliches. –

4

Wenn ich Sie richtig verstehe, möchten Sie Transaktion mit Konto über zwei Beziehungen verwandt werden: debitAccount und creditAccount, ja? Und Sie fragen sich, ob Sie inverse Beziehungen erstellen.

Kurz gesagt, eine Beziehung kann nur die Umkehrung einer anderen Beziehung sein. So können Sie beispielsweise keine Beziehung namens transactions erstellen, die das Gegenteil von debitAccount und creditAccount ist. Stattdessen werden Sie zwei Beziehungen schaffen müssen, wie debitTransactions und creditTransactions (Ich bin sicher, dass Sie für diese von geeigneteren Namen denken werden ...)

Jetzt, da Beziehungen als Sätze modelliert werden (genauer gesagt, NSSet s), können Sie die creditTransactions und debitTransactions Beziehungen für ein bestimmtes Konto verbinden, um alle Transaktionen zu erhalten, mit denen das Konto involviert ist.

eine (möglicherweise besser) Alternative wäre es, eine Zwischeneinheit einzuführen, mit einem Namen wie TransactionAccount, das eine zu-Eins-Beziehung zu sowohl Account und Transaction sowie ein Attribute hat, wie accountRole, die das Konto als das identifiziert, Debit- oder Kreditkonto in Bezug auf diese bestimmte Transaktion. Sie würden inverse zu-viele-Beziehungen auf beiden Transaction und Account mit einem Namen wie transactionAccounts erstellen. Auf diese Weise könnten Sie beispielsweise Folgendes schreiben:

[account valueForKeyPath:@"transactionAccounts.transaction"] 

, um alle Transaktionen für ein bestimmtes Konto abzurufen. Sie könnten eine NSPredicate verwenden, um den Satz nur auf Transaktionen zu filtern, bei denen das Konto das Soll/Haben-Konto war.

+0

Vielen Dank für Ihren Vorschlag! Ich habe einen Weg gefunden, der für mich funktioniert hat, aber dein Input hat geholfen. –