3

Lets say I have three Entitys. Person: name address (to-many-salary) and (to-many-loans)

Salary: income tax Rel: (to-one-Person)

Bills amount Rel: (to-one-person)

How do I perform a fetch that have a result like this:

John Doe, SUM>income, SUM>amount Eva Doe, SUM>income, SUM>amount

Using Swift

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Vegar Flo
  • 61
  • 5
  • 1
    Welcome to SO, please be a bit more specific when asking question: what have you tried, what do you expect, etc. See [how to ask](http://stackoverflow.com/help/how-to-ask) – Nehal Jan 01 '16 at 13:36
  • 1
    Thank you :) I dont know how I can be more specific. Im listing the database with attributes and relations, showing the results I'm after, the language and tagging with related words :) – Vegar Flo Jan 01 '16 at 14:26

1 Answers1

5

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).

pbasdf
  • 21,386
  • 4
  • 43
  • 75
  • Thank you for the answer! I am already using that solution today, but i thought it would be better to do this in the fetch? Speed? Memory usage? Im new with Swift and Xcode, so just asking :) Im using the data in at UITableview. – Vegar Flo Jan 01 '16 at 15:10
  • @VegarFlo I think the KVC method is best, but I've updated my answer with details of the alternative method for info. – pbasdf Jan 01 '16 at 17:02
  • Thank you so much! :) I will do as you say and use the KVC. Just thought it would give better performance by changing the fetch. :) – Vegar Flo Jan 02 '16 at 07:54
  • The KCV might be fast. Measure before you change the code. It all depends on what's already in memory. https://www.objc.io/books/core-data/ – Daniel Eggert Jan 02 '16 at 19:11