Write native SQL in Core Data

时光怂恿深爱的人放手 提交于 2019-12-20 03:11:14

问题


I need to write a native SQL Query while I'm using Core Data in my project. I really need to do that, since I'm using NSPredicate right now and it's not efficient enough (in just one single case). I just need to write a couple of subqueries and joins to fetch a big number of rows and sort them by a special field. In particular, I need to sort it by the sum of values of their child-entites. Right now I'm fetching everything using NSPredicate and then I'm sorting my result (array) manually, but this just takes too long since there are many thousands of results.

Please correct me if I'm wrong, but I'm pretty sure this can't be a huge challenge, since there's a way of using sqlite in iOS applications.

It would be awesome if someone could guide me into the right direction. Thanks in advance.

EDIT: Let me explain what I'm doing. Here's my Coredata model:

And here's how my result looks on the iPad:

I'm showing a table with one row per customer, where every customer has an amount of sales he made from January to June 2012 (Last) AND 2013 (Curr). Next to the Curr there's the variance between those two values. The same thing for gross margin and coverage ratio.

Every customer is saved in the Kunde table and every Kunde has a couple of PbsRows. PbsRow actually holds the sum of sales amounts per month.

So what I'm doing in order to show these results, is to fetch all the PbsRows between January and June 2013 and then do this:

self.kunden = [NSMutableOrderedSet orderedSetWithArray:[pbsRows valueForKeyPath:@"kunde"]];

Now I have all customers (Kunde) which have records between January and June 2013. Then I'm using a for loop to calculate the sum for each single customer.

The idea is to get the amounts of sales of the current year and compare them to the last year. The bad thing is that there are a lot of customers and the for-loop just takes very long :-(


回答1:


This is a bit of a hack, but... The SQLite library is capable of opening more than one database file at a given time. It would be quite feasible to open the Core Data DB file (read/only usage) directly with SQLite and open a second file in conjunction with this (reporting/temporary tables). One could then execute direct SQL queries on the data in the Core Data DB and persist them into a second file (if persistence is needed).

I have done this sort of thing a few times. There are features available in the SQLite library (example: full-text search engine) that are not exposed through Core Data.




回答2:


If you want to use Core Data there is no supported way to do a SQL query. You can fetch specific values and use [NSExpression expressionForFunction:arguments:] with a sum: function.

To see what SQL commands Core Data executes add -com.apple.CoreData.SQLDebug 1 to "Arguments Passed on Launch". Note that this should not tempt you to use the SQL commands youself, it's just for debugging purposes.




回答3:


Short answer: you can't do this.

Long answer: Core Data is not a database per se - it's not guaranteed to have anything relational backing it, let alone a specific version of SQLite that you can query against. Furthermore, going mucking around in Core Data's persistent store files is a recipe for disaster, especially if Apple decides to change the format of that file in some way. You should instead try to find better ways to optimize your usage of NSPredicate or start caching the values you care about yourself.

Have you considered using the KVC collection operators? For example, if you have an entity Foo each with a bunch of children Bar, and those Bars have a Baz integer value, I think you can get the sum of those for each Foo by doing something like:

foo.bars.@sum.baz

Not sure if these are applicable to predicates, but it's worth looking into.



来源:https://stackoverflow.com/questions/18511046/write-native-sql-in-core-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!