Core Data - Fetch All Entities Using the Same Field

Fetching all attribute names that have the same value in Core Data

You propose an entity named Subjects, with attributes named Algebra, Biology, etc, each of which is a boolean that represents whether the user has "learned" that subject. From that, you wish to compose an array comprising all the names of the subjects that the user has learnt.

Although that is possible, it's quite difficult. I recommend instead defining your Subject entity as:

Subject
=======
name (String)
learnt (boolean)

(Note the convention that entity names are usually singular and start with uppercase, whereas attribute names begin with lowercase.) In the first run of your app you might then create a number of instances of the Subject entity, with the required default values:

name        learnt
==== ======
"Algebra" false
"Biology" false
"Calculus" false
... ...

This has the advantage that you can add further subjects at a later date, without needing to modify the structure of your data: it is a simple matter of creating an additional instance with the appropriate name.

As your user progresses through their learning in the app, you can set the value for the learnt attribute to true for the relevant Subject instance. To obtain an array containing only those Subject instances which the user has successfully learnt, you can then use a fetch request with a predicate:

fetchRequest.predicate = NSPredicate(format:"learnt == true")

The array that is returned contains the relevant instances of the Subject entity. It is then simple to obtain the names for display purposes.

You mention in comments having further information about all the subjects. If you model all that in CoreData (eg. having Topic, Lesson, Test entities, etc - I speculate, that's for you to design) you can create relationships to that data from your Subject entity. For example, a Subject might have a relationship to many Topics, each of which has many Lessons and many Tests, etc. That way, when your app starts, you can fetch all the Subject instances and display them in a tableView (showing the name attribute). When the user taps a Subject to begin or continue their learning, you have the relevant Subject instance which provides the link (via the relevant relationship) for you to display the material for the chosen subject.

Core Data: Fetch result from multiple entities or relationship

I'm not sure what you want to achieve but if you want to retrieve an Employee who works in a specific department name and in a specific location, I'll use a the following code:

NSMutableString *queryString = [NSMutableString stringWithFormat:@"deptEmp1.name == %@ AND deptEmp1.location == %@", @"Apple", @"Cupertino"]; 
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects:@"Department",nil]];
[request setIncludesSubentities:YES];

NSArray* returnArray = [self.managedObjectContext executeFetchRequest:request error:&error];
if([returnArray count] > 0) {

Employee* emp = [returnArray objectAtIndex:0];
NSLog(@"%@ %@ %@", emp.name, emp.dept, emp.deptEmp.location);
}

Few notes

Why do you use a lock on the request?
Have you set a inverse rel?
Maybe do you need to set up a one-to-many rel between Department and Employee?

Try and let me know.

Edit

Try this one. I didn't notice the query string in your question.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"deptEmp1.name == %@ AND deptEmp1.location == %@", @"Apple", @"Cupertino"]; 
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
[request setPredicate:predicate];
[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects:@"Department",nil]];
[request setIncludesSubentities:YES];

NSArray* returnArray = [self.managedObjectContext executeFetchRequest:request error:&error];
if([returnArray count] > 0) {

Employee* emp = [returnArray objectAtIndex:0];
NSLog(@"%@ %@ %@", emp.name, emp.dept, emp.deptEmp.location);
}

Edit 2

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects:@"Department",nil]];

NSArray* returnArray = [self.managedObjectContext executeFetchRequest:request error:&error];
for(Employee* emp in returnArray) {

NSLog(@"%@", emp);
NSLog(@"%@", emp.deptEmp);
}

How to fetch only one column Data in Core Data using swift 3

Core data is an object model. It translates rows of the sql database into objects with properties. You are not running queries directly on the SQL, so you cannot do everything in core-data that you could do with SQL. You interact with object which interact with the database. In core-data you can have an object that is not faulted. It means that none of its properties are loaded into memory, but when you need them (when you access a property) it will fetch it from the database. You cannot have a object that has only some of its properties set. They are either all set (ie faulted) or none are set (it is not faulted).

There really isn't much to be gained in most cased by only fetch one or two columns. The extra data transfer is often minimal. The only exception is when you have a large blob of data as as property on the object. In that case you should store the blob on a separate entity and give it a one-to-one relationship. That way the expensive block of data isn't loaded into memory until it is requested.

Core Data fetch one record that has two matching fields

First of all please name variables and parameter labels with starting lowercase letter.

A predicate can have multiple conditions ANDed and ORed

And res.count > 0 ? true : false can be replaced just with !res.isEmpty

func userAcctExists(companyOffice: String, employNo: String) -> Bool {
let fetchRequest = NSFetchRequest<UserAccountMO>(entityName: "UserAccountTbl")
fetchRequest.predicate = NSPredicate(format: "companyOffice == %@ AND employNo == %@", companyOffice, employNo)

let res = try! context.fetch(fetchRequest)
return !res.isEmpty
}

AND and && as well as OR and || are synonyms.

Core data: any way to fetch multiple entities?

What you're trying to do is accomplished by defining entity inheritance in your model,
where "DisplayableObject" would be an abstract class defined as the parent of "Cheese" and "Pirate".

Then you can perform a fetch request on the "DisplayableObject" entity and it will retrieve both entities' objects.

Take a look into this article in the apple documentation: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/KeyConcepts.html

Is it possible to fetch the data of only one attribute of an Entity in Core Data?

It depends on a few things; how many entities are you fetching, do you ever want anything else, what is your real performance problem?

First of all use Instruments to make sure that your problem is actually where you think it is. Core data uses faulting and batching to make it very memory and performance efficient. An entity's attribute data is not brought into memory until it is accessed.

If you really want to only fetch a single attribute from your entities then you can make a fetch request with the propertiesToFetch value set to the attributes you care about. If you do this with a managed object resultType, then AFAIK I know this will use more memory, as it will make all the result objects be a partial fault (with those properties populated) rather than full faults.

If you use the dictionary resultType, then you'll get back no managed objects at all, just an array of dictionaries with the relevant attribute populated.

core data - fetch attribute that match one of the values in an array

Use 'IN' match for this:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"personId IN %@", idsArray];

Core Data: Fetch all entities in a to-many-relationship of a particular object?

You need to actually perform the fetch for the table view controller:

// ...create the fetch results controller...    
NSError *fetchRequestError;
BOOL success = [fetchedResultsController performFetch:&fetchRequestError];


Related Topics



Leave a reply



Submit