Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iphone NSPredicate how to do an INNER JOIN?

I have been looking thru the documentation and some other posts in this site, but I simply cannot understand how to work this out, which is actually very simple in SQL.

Basically I have 2 entities Instruments and Deals. And the "Deals" use an "Instrument" to perform a desired operation. Now I want to list Deals attributes and the Instrument attributes that were used for this deal. So in SQL i would do:

SELECT * FROM Instruments INNER JOIN Deals ON Instruments.ID = Deals.InstrumentID

How would I accomplish this with an NSPredicate?. Any help will be greatly apreciated. Thank you.

-Oscar

like image 642
Oscar Gomez Avatar asked Dec 18 '22 04:12

Oscar Gomez


1 Answers

First, you should do what you can to get out of the SQL mindset. Core Data is not an ORM. It is an object graph management framework that just happens to use SQLite as one possible persistence backend. Although you can view the SQL it uses via environment variables (for debugging), the SQL is a private implementation detail. Core Data could have been implemented without any SQL at all.

So, try not to think in terms of db tables. You have a collection of Deal isntances. You want their properties? Use Key-value Coding to get the properties of those instances and the related Instrument instances. Assuming you have an NSSet instance of Deals, called deals:

[deals valueForKey:@"dealProperty"];

will give you an NSSet of the values of dealProperty from each Deal instance. If you want to get multiple properties at once, you can use -[NSObject(NSKeyValueCoding) dictionaryWithValuesForKeys:]. You can only get keys "one level deep" using this method, so only, e.g. 'dealProperty1', 'dealProperty2' but not 'dealRelation.relationProperty' or 'dealRelation.@count'.

To get "nested" properties, just use a key path:

[deals valueForKeyPath:@"instrument.instrumentProperty"];

will give you a set of the values of the instrumentProperty of the Instrument instance associated with each Deal instance, assuming instrument is a one-to-one relationship from Deal to Instrument. If the relationship is one-to-many, you will get a set of sets of instrumentProperty values.

You can always do this more explicitly (obviously this code doesn't do any thing and isn't even syntactically correct since I've omitted semicolons etc., but it shows the outline):

for(Deal *deal in deals) {
  //use attribute access to get properties of deal and associated instrument
  deal.dealProperty
  deal.instrument.instrumentProperty //for one-to-one

  for(Instrument *instrument in deal.instruments) { //for one-to-many instruments
    instrument.instrumentProperty;
  }
}

using enumeration of the appropriate collections.

like image 80
Barry Wark Avatar answered Dec 31 '22 23:12

Barry Wark