I am using core data first time and facing issue in fetching data from two Tables/Entity.
SQL is as below which is working fine:
Select * from ZMESSAGE msg Left Join ZCONTACT c ON c.ZCHANNEL = msg.ZCHANNEL group by msg.ZCHANNEL Order by msg.ZDATE
Can you please suggest, How to write in NSFetchRequest Statement?
My Entity as below:
I have tried some cases and last one is as below:
NSFetchRequest* fetchGroupSummary = [NSFetchRequest fetchRequestWithEntityName:#"Message"];
NSEntityDescription* entity = [NSEntityDescription entityForName:#"Message" inManagedObjectContext:self.managedObjectContext];
NSRelationshipDescription *groupName = [entity.relationshipsByName objectForKey:#"channels"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"date" ascending:YES];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"channels.channel == channel"];
[fetchGroupSummary setEntity:entity];
[fetchGroupSummary setSortDescriptors:#[sortDescriptor]];
[fetchGroupSummary setPropertiesToFetch:[NSArray arrayWithObjects:groupName, nil]];
[fetchGroupSummary setPropertiesToGroupBy:[NSArray arrayWithObject:groupName]];
[fetchGroupSummary setResultType:NSDictionaryResultType];
[fetchGroupSummary setPredicate:predicate];
NSError* error = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchGroupSummary error:&error];
return results;
Thanks
Related
Consider the above model with to-many relation.
Let's assume I am querying to get managed-objects where patient first or last name is "xyz" (there are multiple records of "xyz").
How to get a unique "xyz" as dictionary object and repeated "xyz" Managed-objets as objects in that dictionary.
So far I am able to get distinct values and also I am able to get array of managed objects where "xyz" is the predicate string.
But I am unable to think of a way to get array of dictionaries with its objects as managed-objects of duplicate values.
I want to have an array of dictionaries with unique value as dictionary name and objets in dictionary should be managed-objects/dictionaries.
Could somebody please help me with this. I will provide more explanation if any part is not understood.
Thanks
#pragma mark - Search Patients By Patient Name
-(NSArray*)GetBillsForPatientwith:(NSString*)name{
NSMutableArray *AllBillsData = [[NSMutableArray alloc]init];
NSArray *_strings = [self GetSplitStrings:name];
NSManagedObjectContext *context = [CoreDataManager GetCoreDataManager].managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:_Claims inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"patient_FirstName" ascending:YES];
NSArray *sortDescriptors = #[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSMutableArray *subPredicates = [NSMutableArray array];
for (NSString *strings in _strings) {
[subPredicates addObject:
[NSPredicate predicateWithFormat:#"patient_FirstName CONTAINS[cd] %# OR patient_LastName contains[cd] %#",strings,strings]];
}
NSCompoundPredicate *predicate_ = [[NSCompoundPredicate alloc]initWithType:NSOrPredicateType subpredicates:subPredicates];
[fetchRequest setReturnsObjectsAsFaults:NO];
[fetchRequest setPredicate:predicate_];
fetchRequest.returnsDistinctResults = YES;
fetchRequest.resultType = NSDictionaryResultType;
fetchRequest.propertiesToFetch = [NSArray arrayWithObjects:[[entity propertiesByName] objectForKey:#"patient_FirstName"],[[entity propertiesByName] objectForKey:#"patient_LastName"], nil];
//fetchRequest.propertiesToGroupBy = [NSArray arrayWithObjects:[[entity propertiesByName] objectForKey:#"patient_FirstName"],[[entity propertiesByName] objectForKey:#"patient_LastName"], nil];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// Handle the error.
}
for (NSDictionary *names in fetchedObjects) {
// [AllBillsData addObject:names];
[AllBillsData addObject:[self GetCorrespondingClaimsForNames:names]];
}
return AllBillsData;
}
//Entangled Method
-(NSArray*)GetCorrespondingClaimsForNames:(id)Names{
NSManagedObjectContext *context = [CoreDataManager
GetCoreDataManager].managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:_Claims inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"patient_FirstName" ascending:YES];
NSArray *sortDescriptors = #[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSMutableArray *subPredicates = [NSMutableArray array];
[subPredicates addObject:
[NSPredicate predicateWithFormat:#"patient_FirstName ==[cd] %# AND patient_LastName ==[cd] %#",[Names valueForKey:#"patient_FirstName"],[Names valueForKey:#"patient_LastName"]]];
NSCompoundPredicate *predicate_ = [[NSCompoundPredicate alloc]initWithType:NSOrPredicateType subpredicates:subPredicates];
[fetchRequest setReturnsObjectsAsFaults:NO];
[fetchRequest setPredicate:predicate_];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// Handle the error.
}
return fetchedObjects;
}
i have to use following query for fetching data:
SELECT * FROM t1.guides AS t1 JOIN guide_category_int AS t2 ON t1.id = t2.guide_id WHERE t2.category_id = 'category_id' AND t1.start_date >= 'today()' AND t1.end_date <= 'today()' ORDER BY t1.name ASC
How can I use this in core data?
Your fetch request will be something like this:
NSManagedObjectContext *context = ...
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Guides" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"guide.category_id == %# and start_date >= %# and end_date <= %#", #"category_id", [NSDate date], [NSDate date]]];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[sort release];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if ([fetchedObjects count] > 0) {
//...
}
[fetchRequest release];
Also you can enable SQLDebug to see raw sql requests, and play with predicate and sort descriptor as you want. How to enable described there
i used this code to select all products that related to specific category but it doesn't work ,, what is the correct predicate that i can use to get all products related to this category
NOTE:
i get the categories list from server alone and insert them ,, and then get products list from server and inserting them ,, but i figured out now that the product don't know his category ,, i'm using restkit library to parse and insert in the database ,, so how i can tell the products that the category ,, the restkit do all the work automatically
how to set to the product list thet i get from server their category ?
//--fetching inserted Results from core data
// Getting products
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"productId" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor , nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// NSPredicate *predicate = [NSPredicate predicateWithFormat:#"category = %# ",tempCategoryHolder];
// [fetchRequest setPredicate:predicate] ;
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Product"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
fetchedObjectsProducts = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
I would do it like this, assuming tempCategoryHolder holds a categoryId:
NSError *error = nil;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Product"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"category.categoryId = %#", tempCategoryHolder];
fetchRequest.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"productId" ascending:YES]];
NSArray *fetchedObjectsProducts = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
Otherwise update the predicate to refer to category object, or different category attribute.
For better understanding my problem imagine your facebook friends; I have one entity "user" and I use that for displaying relationship between friends;
I don't know how to get friends of concrete user using NSFetchRequest
I have two "to many" relationship(see above) and I try to get friends using NSPredicate, but in the end array is empty.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = (NSEntityDescription *)[_dbManager userEntity];
[fetchRequest setEntity:entity];
User *userByUid = [_dbManager userByUid:_currentUid];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:#"sortId" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(friends IN %#)", userByUid];
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchBatchSize:10];
NSArray *array = [_fetchedResultsController.managedObjectContext executeFetchRequest:fetchRequest error:nil];
You have to use the inverse relationship and "ANY":
[NSPredicate predicateWithFormat:#"ANY beFriendsWith == %#", userByUid]
I am trying to pull all the Actions which belong to the latest Session.
In SQL this would be a simple JOIN ... WHERE Session.startTime = MAX(Session.startTime), but with Core Data I can't figure out how to do this without resorting to two steps as below. Any ideas?
// Step 1. Get the latest session
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Session" inManagedObjectContext:self.managedObjectContext]];
[request setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"startTime" ascending:NO]]];
[request setFetchLimit:1];
Session *lastSession = nil;
NSArray *objects = [self.managedObjectContext executeFetchRequest:request error:NULL];
if ([objects count] > 0)
{
NSLog(#"max: %#", [objects objectAtIndex:0]);
lastSession = [objects objectAtIndex:0];
}
// Step 2. Get that session's actions
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Action" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sectionSort = [[NSSortDescriptor alloc] initWithKey:#"session.startTime" ascending:NO selector:nil];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"startTime" ascending:NO selector:nil];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sectionSort, sort, nil]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"session.startTime = %#", lastSession.startTime];
//**Can't I do something like this instead?**
//NSPredicate *predicate = [NSPredicate predicateWithFormat:#"session.startTime = session.#max.startTime"];
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchBatchSize:10];
[self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"session.startTime" cacheName:#"ActionHistory"];
self.fetchedResultsController.delegate = self;
NSError *error;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort(); // Fail
}
Edit: I do need to stick with using NSFetchedResultsController due reasons not fully detailed above.
I would advise you to make a relationship beetwen Session and Action.
Then, after you fetch the session you need, you could get all that session's actions as easy ss lastSession.actions.
Edit
Maybe you can do
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"session = %#",lastSession];