9

関連するモデルをマージして作成された NSManagedObjectModel 内でエンティティが常に使用される場合、個別の NSManagedObjectModels で定義されているエンティティ間の関係をモデル化することは可能ですか?

たとえば、モデル 1Fooが関係 (1 対 1)を持つエンティティをtoBar定義し、モデル 2が関係 (1 対 1) を持つエンティティを定義するとします。を使用して CoreData スタックを構築し、モデル 1 とモデル 2 をマージします。モデル内の関係であるかのように動作するように、データ モデラーまたはプログラムでこれらの関係を定義する方法はありますか?BartoFoo-[NSManagedObjectModel mergedModelFromModels]

4

1 に答える 1

16

toBarモデル 1 もモデル 2 も、整形式でない限り、つまり、とのtoFoo関係に宛先がない限り、実行時にロードできません。さらに、モデル 1 とモデル 2 に同じ名前のモデルがある場合、それらからマージされたモデルを作成することはできません。それらは合体せず、衝突します。これはエラーです。

ただし、NSManagedObjectModelAPI を手動で使用して各モデルをロードし、両方のエンティティを含む新しいモデルを手動で作成できます。およびクラス (NSEntityDescriptionおよびNSPropertyDescriptionそのサブクラス) はNSCopyingプロトコルを実装しているため、ほとんどの場合、各コンポーネント モデルからモデル全体に​​プロパティをコピーするだけで済みます。

さらに、これらのNS*DescriptionクラスはすべてuserInfo、Xcode のデータ モデリング ツールで編集できるディクショナリをサポートしています。これを使用して、リレーションシップの宛先にスタンドインとしてタグを付けるなどのことができます。たとえば、モデル 1 では、キーを持つBarエンティティがあり、マージされたモデルを作成するときにそれをチェックして、代わりに実際のエンティティを使用するシグナルとして使用できます。userInfoMyRealEntity

また、スタンドイン エンティティにスタンドイン逆関係を配置することもできます。これらは、マージ後に実際の逆数に置き換えられます。ただし、すべてのモデルでスタンドイン エンティティを完全に複製する必要はありません。スタンドインエンティティの実際のモデルで使用される逆の関係のみが必要です。

したがって、実物Fooname属性があり、実物バーに属性kindがある場合、代役はそれらを必要とせず、代役と関係だけがFoo必要です。BartoBartoFoo

私が話していることを示すコードを次に示します。

- (NSManagedObjectModel *)mergeModelsReplacingDuplicates:(NSArray *)models {
    NSManagedObjectModel *mergedModel = [[[NSManagedObjectModel alloc] init] autorelease];

    // General strategy:  For each model, copy its non-placeholder entities
    // and add them to the merged model. Placeholder entities are identified
    // by a MyRealEntity key in their userInfo (which names their real entity,
    // though their mere existence is sufficient for the merging).

    NSMutableArray *mergedModelEntities = [NSMutableArray arrayWithCapacity:0];

    for (NSManagedObjectModel *model in models) {
        for (NSEntityDescription *entity in [model entities]) {
            if ([[entity userInfo] objectForKey:@"MyRealEntity"] == nil) {
                NSEntityDescription *newEntity = [entity copy];
                [mergedModelEntities addObject:newEntity];
                [newEntity release];
            } else {
                // Ignore placeholder.
            }
        }
    }

    [mergedModel setEntities:mergedModelEntities];

    return mergedModel;
}

これが機能するのはNS*Description、Core Data 内のオブジェクトのコピーが、リレーションシップの宛先エンティティおよびその逆に関して (およびエンティティのサブエンティティに対しても)、値ではなく名前によるためです。したがって、モデルが変更可能である間 (つまり、モデルとして設定される前) に、NSPersistentStoreCoordinatorこのようなトリックを使用してモデルを複数のモデルに分割できます。

于 2008-09-26T06:47:35.783 に答える