Fetching child sum from Core Data
This is probably most easily done using Key Value Coding "collection operators" (see here) rather than a fetch. For each person
:
let name = person.name
let totalIncome = person.valueForKeyPath("salary.@sum.income")
let totalLoans = person.valueForKeyPath("loans.@sum.amount")
If performance is an issue, you might improve things by amending the fetch request (for the Person objects) to "prefetch" the related Salary
and Bills
objects:
fetchRequest.relationshipKeyPathsForPrefetching = ["salary", "loans"]
Alternatively, it is possible to retrieve the required information all in one fetch, though I do not recommend it because it requires changing the fetchRequest to return an array of dictionaries rather than an array of NSManagedObjects
. This makes subsequent processing (eg. populating your table view) more difficult.
// Define NSExpression and NSExpressionDescription for the total income
let incomeED = NSExpressionDescription()
incomeED.expression = NSExpression(forKeyPath: "salary.@sum.income")
incomeED.name = "totalIncome"
incomeED.expressionResultType = .Integer64AttributeType
// Define NSExpression and NSExpressionDescription for the total amount
let amtED = NSExpressionDescription()
amtED.expression = NSExpression(forKeyPath: "loans.@sum.amount")
amtED.name = "totalLoans"
amtED.expressionResultType = .Integer64AttributeType
// specify attributes and expressions to fetch
fetchRequest.propertiesToFetch = ["name", incomeED, amtED]
// specify dictionary return type (required to process NSExpressions)
fetchRequest.resultType = .DictionaryResultType
The result of the fetch will be an array of dictionaries; each dictionary will have keys "name", "totalIncome" and "totalLoans" (with corresponding values).
Fetching child count from Core Data
The following should work
let totalIncome = item.value(forKeyPath: "attribute.@sum.income") as? Int ?? 0
Sum on child object while displaying parent object - Core Data
First of all, you shouldn't think of entities being in a parent-child/tree structure unless your object graph actively enforces such a structure. In most cases it won't and any two entities are structural equals. That appears to be the case with your 'Customer' and 'Order' entities.
It's an important concept to grasp because unlike a conventional tree-structure, in a Core Data data graph, you can enter the graph at any instance of any entity and walk the relationships in any direction e.g. You don't have to always fetch a Customer
object to start, you can if needed fetch a Order
object just as easily.
In this particular case you are fetching Customer
objects and you want to find all associated Order
objects. Your data model should look something like this:
Customer{
name:string
orders<-->>Order.customer
}
Order{
item:string
cost:number
customer<<-(required)->Customer.orders
}
Now, every time you create a new Order
object you automatically link it the appropiate Customer object. When you fetch any particular Customer
object all it's related Order
objects are available in the Customer.orders
relationship.
If you wanted to sum the cost of all a customer's orders, you could use a collection operator like so:
NSNumber *orderSum=[Customer.order valueForKeyPath:@"@sum.orders.cost"];
Relationships are very important to Core Data.
Core Data sum in relationship
Your using the @sum with the correct syntax. Most likely, you have just got another part of the keypath wrong e.g. "expenses" instead of "expense". Alternatively, you may be fetching the wrong entity.
If all you want to do is fetch this sum, do an attribute fetch and set your return type to dictionary. (See NSFetchRequest and Core Data Programming Guide) docs for details. That returns an array of dictionaries whose sole key is the attribute name and whose sole value is the value of selected attribute of one managed object. It's faster and uses fewer resources than fetching full objects.
When loading an NSManagedObject from Core Data, do I get it's children for free?
When seeing your AlarmMO
model, you can just fetch your AlarmMO
model which will hold the list of NotificationUuidMO
in notificationUuidChildren
Set. So there is no need to fetch NotificationUuidMO
separately.
And AlarmMO to NotificationUuidMO
is one to many relationship. So you can get notificationUuidChildren
from AlarmMO
and alarmParent
from NotificationUuidMO
.
To add NotificationUuidMO
to notificationUuidChildren
Set, you can use Core-Data generated accessors given in extension AlarmMO
.
Example:
let notificationUuid = NotificationUuidMO....
let alarmMO = AlarmMO....
alarmMO.addToNotificationUuidChildren(notificationUuid)//Here your notificationUuid will be added to `notificationUuidChildren` Set and `alarmParent` of your `notificationUuid` will be automatically assigned to `alarmMO`.
Swift - CoreData NSPredicate - Fetch Children of parent
The key path used in the fetch request must match the actual name
of the Core Data relationship, in your case "agendaEvents",
there is no implicit "parent" relationship:
fetchRquest.predicate = NSPredicate(format: "agendaEvents == %@", event)
Even better, use #keyPath
and the %K
expansion
fetchRquest.predicate = NSPredicate(format: "%K == %@",
#keyPath(AgendaDate.agendaEvents), event)
so the that compiler checks the validity of the key path.
This helps to avoid using unknown key paths or typos.
Note that a better relationship name would be "agendaEvent"
or just "event", with the singular form for a to-one relationship.
Core Data: fetch request for fetching entities in a one-many-one relationship
I got lucky and found this answer
NSPredicate acting strange in NSFetchedResultsController
The question was worded differently, which is why it took awhile for me to find it. Basically, the predicate I'm looking for is of the following format:
[NSPredicate predicateWithFormat:@"SUBQUERY(parent, $x, $x.grandparent == %@).@count != 0", grandParent];
IOS/Objective C/Core Data: Sum all the values for an attribute from query
You can use key-value coding:
NSNumber *orderTotal = [arrayWhoseSumIsToBeCalculated valueForKeyPath:@"@sum.self"];
Related Topics
How to Implement a 'Next' Property to a Caseiterable Enum in Swift
Changing The Color of a Button in Swiftui on Tvos
How to Edit Swift Error Breakpoint
Swift Tdd & Async Urlsession - How to Test
Does Swift Optimise Chained Creation and Copy of Structs
Xcode11 Error "Open(_:Options:Completionhandler:) Is Unavailable in Application Extensions"
Play Sound with a Little Delay
Could Not Find a Storyboard Named 'Maintabcontroller' in Bundle Nsbundle
Swift 3 - Pass Struct by Reference via Unsafemutablerawpointer
Spritekit Skphysicsjointfixed Odd Behaviour
Dyld: Library Not Loaded: @Rpath/Libswiftdispatch.Dylib
"Raw Value for Enum Case Is Not Unique" for Swift Enum with Float Raw Values
Swift Compiler Error Int Is Not Convertible to Cgfloat
Create a Navigationlink Without Back Button Swiftui
Send Mail with File Attachment