与Fetched属性交叉存储弱关系? [英] Cross-Store weak relationship with Fetched Properties?

查看:178
本文介绍了与Fetched属性交叉存储弱关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将我的参考数据与我的Core Data模型中的用户数据分开,以简化我的应用程序的未来更新(并且因为我计划将数据库存储在云上,并且不需要将参考数据存储在云作为我的应用程序的一部分)。因此,我一直在寻找一种方法来使用获取的属性来编码跨存储关系。我没有找到任何示例实现这个。



我有一个Core Data模型使用两个配置:




  • 数据模型配置1:UserData(与用户相关的实体)


  • 应用程序本身)




我为两个配置设置了两个不同的SQLite持久存储。




  • UserData配置(和存储)包含实体User


  • 存储)包含实体Type和Item。




我想创建两个单向弱关系如下:




  • 用户有唯一的类型


  • 用户有许多项目




>


  • 如何设置我的属性?


  • 每个关系需要2个属性(一个用于存储唯一ID,另一个用于访问我的提取结果)?



  • 有人可以给我一个示例实现这个吗?




作为Marcus的回答的后续:



通过论坛和文档,我读到我应该使用我的实体实例的URI表示,而不是objectID。这是什么原因?

  //获取要引用的对象的URI 
NSURL * uriObjectB [ myObjectB objectID] URIRepresentation];

接下来,我不知道如何将我的对象B URI(NSURL)存储在父对象A作为弱关系?我应该使用什么属性类型?如何转换?我听说过存档...?



然后,后来我应该以同样的方式检索管理对象(通过unconvert / unarchive URIRepresentation) p>

  //从URI获取对象ID 
NSManagedObjectID * idObjectB = [storeCoordinator managedObjectIDForURIRepresentation:[[myManagedObject objectID] URIRepresentation] ];

//获取idOjectB的管理对象...

最后但并非最不重要的是,我在我的实体A中声明了两个属性,一个用于持久化URI需求,另一个用于检索直接对象B?

  NSURL * uriObjectB [objectA uriObjectB]; 

ObjectB * myObjectB = [objectA objectB];

正如你可以阅读,我真的想念一些简单的例子来实现弱关系!我真的很感谢一些帮助。

解决方案

拆分数据是正确的答案。参考数据不应与云同步,特别是因为iCloud对允许应用程序同步和存储在文档中的软限制。



要创建软引用到存储(他们不需要是SQLite,但它是一个好主意,一般的应用程序性能),你将需要有一些类型的唯一键,可以从另一侧引用;一个好的旧式外键。



从这里你可以在模型中创建一个获取的属性来引用实体。



虽然这种关系不能直接排序,你可以通过排序索引创建顺序,或者如果它有一个逻辑排序,然后你可以排序它一旦你检索数据(我使用方便的方法,这返回一个有序的数组,而不是设置)。



我可以建立一个例子,但你真的是在正确的轨道。唯一有趣的部分是迁移。当您检测到迁移情况时,您需要在建立核心数据堆栈之前之前独立迁移每个存储。



示例



想象一下,你有一个UserBar实体以及参考存储中的RefBar实体。 RefBar然后将与UserBar具有fetchedProperty关系,从而创建ToOne关系。

  UserBar 
- --------
refBarID:NSInteger

RefBar
--------
标识符:NSInteger

然后,您可以在建模器中的RefBar实体上创建一个获取的属性,其谓词为:



$ FETCHED_PROPERTY.refBarID ==标识符



允许谓词userBarFetched的名称



现在,将返回一个数组,所以我们想添加一个方便的方法到RefBar

  @class UserBar; 

@interface RefBar:NSManagedObject

- (UserBar *)userBar;

@end

@implementation RefBar

- (UserBar *)userBar
{
NSArray * fetched = [self valueForKey:@userBarFetched];
return [fetched lastObject];
}

@end

要创建ToMany,除了你的方便方法会返回一个数组,你会在返回数组之前对数组进行排序。



As Heath Borders 提到,可以向 NSFetchedProperty 添加排序必须在代码中做。我个人总是发现它浪费,不使用该功能。如果我可以在建模器中设置排序,这可能会更有用。



使用ObjectID



不推荐使用ObjectID或URIRepresentation。 ObjectID(以及该ObjectID的URIRepresentation)可以并将改变。每当迁移数据库时,值将更改。



弱关系



您只需要一个值,并且存储外部标识符。在你的对象子类中,你只需要实现检索对象(或对象)的访问器。


I would like to separate my reference data from my user data in my Core Data model to simplify future updates of my app (and because, I plan to store the database on the cloud and there is no need to store reference data on the cloud as this is part of my application). Therefore, I've been looking for a while for a way to code a cross-store relationship using fetched properties. I have not found any example implementations of this.

I have a Core Data model using 2 configurations :

  • data model config 1 : UserData (entities relative to user)

  • data model config 2 : ReferenceData (entities relative to application itself)

I set up 2 different SQLite persistent stores for both config.

  • UserData config (and store) contains entity "User"

  • ReferenceData config (and store) contains entities "Type" and "Item".

I would like to create two single-way weak relationships as below :

  • A "User" has a unique "Type"

  • A "User" has many "Items"

Here are my questions :

  • How do I set up my properties?

  • Do I need 2 properties for each relation (one for storing Unique ID and another to access my fetched results)?

  • Could this weak relationship be ordered?

  • Could someone give me an example implementation of this?

As a follow-on to Marcus' answer:

Looking through the forums and docs, I read that I should use the URI Representation of my entity instance instead of objectID. What is the reason behind this?

// Get the URI of my object to reference 
NSURL * uriObjectB [[myObjectB objectID] URIRepresentation];

Next, I wonder, how do I store my object B URI (NSURL) in my parent object A as a weak relationship? What attribute type should I use? How do I convert this? I heard about archive... ?

Then, later I should retrieve the managed object the same way (by unconvert/unarchive the URIRepresentation) and get Object from URI

// Get the Object ID from the URI 
NSManagedObjectID* idObjectB = [storeCoordinator managedObjectIDForURIRepresentation:[[myManagedObject objectID] URIRepresentation]];

// Get the Managed Object for the idOjectB ...

And last but not least, shouId I declare two properties in my entity A, one for persisting of URI needs and another for retrieving direclty object B?

NSURL * uriObjectB [objectA uriObjectB];

ObjectB * myObjectB = [objectA objectB];

As you can read, I really miss some simple example to implement thes weak relationships ! I would really appreciate some help.

解决方案

Splitting the data is the right answer by far. Reference data should not be synced with the cloud, especially since iCloud has soft caps on what it will allow an application to sync and store in documents.

To create soft references across to stores (they do not need to be SQLite but it is a good idea for general app performance) you will need to have some kind of unique key that can be referenced from the other side; a good old fashioned foreign key.

From there you can create a fetched property in the model to reference the entity.

While this relationship cannot be ordered directly you can create order via a sort index or if it has a logical sort then you can sort it once you retrieve the data (I use convenience methods for this that return a sorted array instead of a set).

I can build up an example but you really are on the right track. The only fun part is migration. When you detect a migration situation you will need to migrate each store independently before you build up your core data stack. It sounds tricky but it really is not that hard to accomplish.

Example

Imagine you have a UserBar entity in the user store and a RefBar entity in the reference store. The RefBar will then have a fetchedProperty "relationship" with a UserBar thereby creating a ToOne relationship.

UserBar
----------
refBarID : NSInteger

RefBar
--------
identifier : NSInteger

You can then create a fetched property on the RefBar entity in the modeler with a predicate of:

$FETCHED_PROPERTY.refBarID == identifier

Lets name that predicate "userBarFetched"

Now that will return an array so we want to add a convenience method to the RefBar

@class UserBar;

@interface RefBar : NSManagedObject

- (UserBar*)userBar;

@end

@implementation RefBar

- (UserBar*)userBar
{
    NSArray *fetched = [self valueForKey:@"userBarFetched"];
    return [fetched lastObject];
}

@end

To create a ToMany is the same except your convenience method would return an array and you would sort the array before returning it.

As Heath Borders mentioned, it is possible to add a sort to the NSFetchedProperty if you want but you must do it in code. Personally I have always found it wasteful and don't use that feature. It might be more useful if I could set the sort in the modeler.

Using the ObjectID

I do not recommend using the ObjectID or the URIRepresentation. The ObjectID (and therefore the URIRepresentation of that ObjectID) can and will change. Whenever you migrate a database that value will change. You are far better off creating a non-changing GUID.

The weak relationship

You only need a single value on the M side of the relationship and that stores the foreign identifier. In your object subclass you only need to implement accessors that retrieve the object (or objects).

这篇关于与Fetched属性交叉存储弱关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆