Potrzebuję wykonać operację typu "dołącz" na dwóch tabelach/modelach z mojego magazynu danych podstawowych i mam problem ze znalezieniem dobrych przykładów na uzyskanie czegoś tak to działa.Podstawowe dane - proste pobieranie typu JOIN
To dość proste, co muszę zrobić. Mam dwa modele/tabele: lokalizacje i location_categories, w których lokalizacje zawierają szczegóły lokalizacji/zakładu (wraz z unikalnym identyfikatorem), a tabela location_categories zawiera identyfikator category_id z powiązanymi id_właściwości. Muszę wybrać wszystkie lokalizacje, w których, biorąc pod uwagę identyfikator category_id, dołącza ona do dwóch tabel/modeli. Gdyby to było proste SQL, to będzie wyglądać następująco (i ta kwerenda działa gdy uruchamiam go przed faktycznym DB SQLite):
// pretend we passed in a catID of 29:
SELECT * FROM zlocation where zlocid in (select zlocid from zloccategory where zcatid = 29)
Więc jak widać, to dość prosta. Czy istnieje sposób, aby to zrobić bez konieczności wykonywania dwóch przydziałów i pętli for? Mój obecny kod celu do zrobienia tego jest poniżej i działa dobrze, ale oczywiście jest strasznie powolny i nieefektywny, ze względu na dużą ilość danych znajdujących się w obu tabelach. For-pętle powodują ogromne spowolnienie, a mój gut mówi mi, że ta praca naprawdę należy zrobić po stronie DB/Core danych rzeczy:
- (NSMutableArray *) fetchLocsWithCatID:(NSString *)catID {
NSMutableArray *retArr = [[NSMutableArray alloc] init];
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:MODELNAME_LOCCATEGORIES inManagedObjectContext:context]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat:@"catID == %@", catID]];
NSError *error;
NSArray *locCats = [context executeFetchRequest:fetchRequest error:&error];
NSArray *allLocsArr = [self fetchAllDataForTable:MODELNAME_LOCATION]; // this retrieves contents of entire table
for (Location *currLoc in allLocsArr) {
for (LocCategory *currLocCat in locCats) {
if ([currLoc.locID isEqualToString:currLocCat.locID]) {
if (![retArr containsObject:currLoc]) {
[retArr addObject:currLoc];
}
}
}
}
return retArr;
}
jakieś przemyślenia na temat tego, czy jest to możliwe w jednym predicate/fetch? Czy może nie ma lepszego sposobu na połączenie tych dwóch NSArrays poprzez kod celu?
Z góry dziękuję za wszelkie wskazówki, które możesz w tej sprawie zaoferować!
Zaznaczam to jako najlepszą odpowiedź, ponieważ wspomniałeś o potrzebie połączenia również relacji. To było coś, co mnie jeszcze nie zaskoczyło, nawet po tym, jak zaimplementowałem relacje w modelu. Dziękuję Ci! – svguerin3