Pertanyaan Tambahkan atribut baru ke Hubungan Entitas Inti Data yang ada


Saya tidak yakin apakah pemahaman saya tentang hubungan Data Inti cacat karena saya tidak dapat mencapai apa yang ingin saya lakukan.

Saya memiliki 2 entitas yang dibuat untuk mengelola Obrolan pada aplikasi dan hubungan satu-ke-Banyak antara pengguna dan pesan. Jadi, pengguna dapat memiliki banyak pesan tetapi pesannya hanya Anda pengguna (pencipta).

enter image description here

Saya mencoba memperbarui ChatUser hubungan entitas ketika pesan baru ditambahkan di mana koneksi antara ChatUser ID dan ChatMessage didirikan. Saya bisa melakukan ini tetapi masalah muncul ketika saya pergi untuk menambahkan pesan baru ke yang sudah ada userId. Semua yang saat ini sedang dicapai adalah menambahkan tambahan userId ke ChatUser alih-alih menambahkan hanya hubungan ke yang ada UserId.

NSManagedObjectContext *context = [self managedObjectContext];
NSError *error = nil;

// 4 . Get Timestamp for Rippll
float timestamp = @([[NSDate date] timeIntervalSince1970]).floatValue;
 NSString * jayID = @"eu-west-1:be6457ce-bac1-412d-9307-e375e52e22ff";

  NSString *message = @"Science string!";

// Create a new managed object
ChatUser *chatUserManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"ChatUser" inManagedObjectContext:context];
Chat *chatManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"ChatMessage" inManagedObjectContext:context];
Timeline *timelineManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"Timeline" inManagedObjectContext:context];

// 3 . Save Timeline
[timelineManagedObject setEvent:chatEvent];
[timelineManagedObject setTimestamp:[NSNumber numberWithFloat:timestamp]];
[timelineManagedObject setMeta:@""];
[timelineManagedObject setViewed:@NO];
[timelineManagedObject setEventID:jayID];

//Save UserMessage
[chatManagedObject setChatId:jayID];
[chatManagedObject setTimestamp:[NSNumber numberWithFloat:timestamp]];
[chatManagedObject setMessage:message];
[chatManagedObject setMedia:@""];

//Check if value exists
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ChatUser"];
[request setPredicate:[NSPredicate predicateWithFormat:@"userId = %@", jayID]];
[request setFetchLimit:1];

NSArray *entities = [[context executeFetchRequest:request error:&error] mutableCopy];

if (entities.count == 0) {

    NSLog(@"GOOD TO ADD");
        // no matching object

    [chatUserManagedObject setUserId:jayID];

    //Create Relationship
    [chatUserManagedObject addChatObject:chatManagedObject];

} else {

    NSLog(@"IT EXISTS!");

    [chatManagedObject setChat:chatUserManagedObject];

}

// Save the object to persistent store
if (![context save:&error]) {
    NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
}

14
2018-04-11 23:07


asal


Jawaban:


Saya kurus, @PangHoMing berada di jalur yang benar, tetapi menggunakan Magical Records. Mari kita lakukan hanya dengan CD:

Pertama, ganti nama hubungan. Mungkin di ChatMessage harus ada hubungan to-1 bernama user (atau chatUser) dan masuk ChatUser harus ada hubungan to-N messages (atau chatMessages). Mereka harus menjadi hubungan terbalik.

Selanjutnya Anda harus meminta keberadaan pengguna sebelum membuatnya. (Jika tidak, Anda membuat pengguna hantu.) Anda mendapat kode untuk itu:

// Create message as you did
ChatMessage *message = …;
…

// The user will go here
ChatUser *user; // Do not use types in names unless conversion is subject of your code

// Look for an existing one
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ChatUser"];
[request setPredicate:[NSPredicate predicateWithFormat:@"userId = %@", jayID]];
[request setFetchLimit:1];

NSArray *entities = [[context executeFetchRequest:request error:&error] mutableCopy];

if (entities.count == 0) 
{
  // Only if there is none, create one  
  user = [NSEntityDescription insertNewObjectForEntityForName:@"ChatUser" inManagedObjectContext:context];
  // Set-up user's properties
  …
} 
else 
{
  // Use the existing one
  user = entities[0];
}

[message setValue:user forKey:@"user"]; // message.user = user;

Seperti yang disebutkan oleh orang lain, hubungan terbalik dipertahankan oleh CD. Namun, Anda dapat menggunakan hubungan terbalik untuk menambahkan pesan, jika ini lebih mudah dibaca untuk Anda:

[[user mutableSetValueForKey:@"messages"] addObject:message]; // [user addMessagesObject:message]

Ini akan mempertahankan hubungan "asli" juga.


3
2018-04-29 12:47



Data Inti secara otomatis akan mengatur ujung hubungan lainnya setelah Anda memulai dari kedua arah. Anda dapat menambahkan ke ChatUser's chat koleksi atau set ChatMessage's chat dengan sebuah contoh dari sebuah NSManagedObject dan itulah yang harus Anda lakukan. Perhatikan bahwa proses ini tidak mengharuskan Anda mengelola kunci asing, kerumitan itu disarikan dari Anda. Anda masih dapat menyimpan ID sisi-server jika mereka membantu Anda berinteraksi dengan API, tetapi mereka tidak diperlukan untuk Data Inti.

Saya akan merekomendasikan mengubah satu ujung dari hubungan sehingga keduanya tidak diberi nama hal yang sama. Pertimbangkan memperbarui ChatUserhubungan menjadi messages atau yang serupa.


6
2018-04-22 19:14



  1. Anda harus memeriksa dulu apakah ada entitas ChatUser yang sudah ada dalam Konteks Anda. Cukup dengan mencoba mendapatkan ChatUser dengan userId itu, jika ada pengembalian ChatUser yang berarti bahwa ChatUser sudah dikurangkan; jika kembali nil itu berarti tidak ada entitas ChatUser dengan userId yang dibuat.
  2. Untuk menangani 1 - banyak relasi, Anda harus menggunakan [message setChatUser: chatUser] daripada chatUser addMessageObject

Jangan ragu untuk mengajukan pertanyaan lanjutan jika Anda memilikinya. Tepuk tangan!


1
2018-04-12 07:18



Coba terapkan sesuatu seperti ini. Solusi ini hampir sama seperti yang diusulkan oleh Amin Negm-Awad

NSManagedObjectContext *context = [self managedObjectContext];
NSError *error = nil;

// 4 . Get Timestamp for Rippll

NSString * jayID = @"eu-west-1:be6457ce-bac1-412d-9307-e375e52e22ff";

NSString *message = @"Science string!";

//Check if value exists
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ChatUser"];
[request setPredicate:[NSPredicate predicateWithFormat:@"userId = %@", jayID]];
[request setFetchLimit:1];

NSArray *entities = [[context executeFetchRequest:request error:&error] mutableCopy];

ChatUser *chatUserManagedObject = nil;

if (entities.count)
{
    NSLog(@"IT EXISTS!");
    chatUserManagedObject = entities.firstObject;
}
else
{
    NSLog(@"GOOD TO ADD");
    chatUserManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"ChatUser" inManagedObjectContext:context];
    [chatUserManagedObject setUserId:jayID];
}

// Create a new managed object

Chat *chatManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"ChatMessage" inManagedObjectContext:context];

//Save UserMessage
[chatManagedObject setChatId:jayID];
[chatManagedObject setTimestamp:[NSDate date]];
[chatManagedObject setMessage:message];
[chatManagedObject setMedia:@""];

[chatUserManagedObject addChatObject:chatManagedObject];

// Save the object to persistent store
if (![context save:&error]) {
    NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
}

1
2018-04-29 15:07