2014-01-30 82 views
0

我有一個應用程序在表中有很多數據,而且我正在編寫一個獲取一小部分數據的移動應用程序。表中的數據使用ID作爲關係,我試圖將它加載到核心數據模型中並保留關係。從現有的數據庫ID關係中加載核心數據關係

但似乎沒有一種簡單的方法可以告訴Core Data,「對於這種關係,我需要一個外鍵給這個其他表。」相反,我有這個怪物(這是隻有六的一個異步RestKit查詢的簡化版本,都回來了填充數據庫):

[manager postObject:nil path:@"api/shiftservice/get" parameters:@{@"workerIds": @[@1]} success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 
    NSLog(@"Loaded shifts: %d", [[mappingResult array] count]); 
    NSManagedObjectContext *context = [AppDelegate managedObjectContext]; 

    NSSet *positions = [context fetchObjectsForEntityName:@"NWPosition"]; 
    NSDictionary *positionDict = [NSMutableDictionary new]; 
    for (NWPosition *position in positions) [positionDict setValue:position forKey:position.positionId.stringValue]; 

    NSSet *workers = [context fetchObjectsForEntityName:@"NWWorker"]; 
    NSDictionary *workerDict = [NSMutableDictionary new]; 
    for (NWWorker *worker in workers) [workerDict setValue:worker forKey:worker.workerId.stringValue]; 

    NSSet *shifts = [context fetchObjectsForEntityName:@"NWShift"]; 
    for (NWShift *shift in shifts) 
    { 
     NWPosition *position = [positionDict valueForKey:shift.positionId.stringValue]; 
     position.shifts = [context fetchObjectsForEntityName:@"NWShift" withPredicateFormat:@"positionId = %d", position.positionId]; 
     shift.position = position; 

     NSSet *tradesAsGetShift = [context fetchObjectsForEntityName:@"NWTrade" withPredicateFormat:@"getShiftId = %@", shift.shiftId]; 
     for (NWTrade *trade in tradesAsGetShift) trade.getShift = shift; 
     shift.tradesAsGetShift = tradesAsGetShift; 

     NSSet *tradesAsGiveShift = [context fetchObjectsForEntityName:@"NWTrade" withPredicateFormat:@"giveShiftId = %@", shift.shiftId]; 
     for (NWTrade *trade in tradesAsGiveShift) trade.giveShift = shift; 
     shift.tradesAsGiveShift = tradesAsGiveShift; 

     NWWorker *worker = [workerDict valueForKey:shift.workerId.stringValue]; 
     worker.shifts = [context fetchObjectsForEntityName:@"NWShift" withPredicateFormat:@"workerId = %d", worker.workerId]; 
     shift.worker = worker; 
    } 
} failure:^(RKObjectRequestOperation *operation, NSError *error) { 
    NSLog(@"Failed to load shifts with error: %@", [error localizedDescription]); 
}]; 

我用馬特加拉格爾的單行的修改版本請致電http://www.cocoawithlove.com/2008/03/core-data-one-line-fetch.html獲取fetchObjectsForEntityName

無論如何,這對我來說似乎非常可怕,就像我錯過了一些明顯的東西。有什麼方法可以告訴Core Data關於數據庫風格的外鍵嗎?有沒有簡單的方法來填充它們,如果沒有?因爲爲每一個實體做這麼多提取並不是正確的做法。如果RestKit在這裏提供幫助,那就更好了。

+1

RestKit應該處理外鍵(核心數據不)。顯示您收到的JSON和您擁有的映射。您是否將外鍵關係添加到映射中? – Wain

回答

0

感謝Wain和他的富有洞察力的評論,我設法讓RestKit以合理優雅的方式爲我做到這一點。以下是我如何設置外鍵關係。我建立了每個關係的兩端,以便任何一組數據都可以首先進入,並且關係仍然可以正確填充。

首先,我設置的經理,告訴它使用JSON序列:

RKManagedObjectStore *store = [AppDelegate managedObjectStore]; 

RKObjectManager *manager = [[RKObjectManager alloc] initWithHTTPClient:oauthClient]; 
[RKObjectManager setSharedManager:manager]; 
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:RKMIMETypeJSON]; 
[manager.HTTPClient registerHTTPOperationClass:[AFJSONRequestOperation class]]; 
[manager registerRequestOperationClass:[AFJSONRequestOperation class]]; 
[manager setAcceptHeaderWithMIMEType:RKMIMETypeJSON]; 
[manager setRequestSerializationMIMEType:RKMIMETypeJSON]; 
manager.managedObjectStore = store; 

接下來,我建立連接和響應描述:

NSManagedObjectContext *context = [AppDelegate managedObjectContext]; 
NSDictionary *orgRels = [[NSEntityDescription entityForName:@"NWOrg" inManagedObjectContext:context] relationshipsByName]; 
NSDictionary *positionRels = [[NSEntityDescription entityForName:@"NWPosition" inManagedObjectContext:context] relationshipsByName]; 
// ... 

NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); 

NSArray *orgConnections = 
@[[self connectionForRelation:@"positions" localKey:@"orgId" foreignKey:@"orgId" withRels:orgRels], 
    [self connectionForRelation:@"workers" localKey:@"orgId" foreignKey:@"orgId" withRels:orgRels]]; 
[manager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping: 
    [self entityMappingForName:@"NWOrg" fromDictionary:@{@"orgId": @"orgId", @"orgName": @"orgName"} withKey:@"orgId" andConnections:orgConnections] 
    method:RKRequestMethodAny pathPattern:@"api/orgservice/get" keyPath:nil statusCodes:statusCodes]]; 

NSArray *positionConnections = 
@[[self connectionForRelation:@"org" localKey:@"orgId" foreignKey:@"orgId" withRels:positionRels], 
    [self connectionForRelation:@"shifts" localKey:@"positionId" foreignKey:@"positionId" withRels:positionRels]]; 
[manager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping: 
    [self entityMappingForName:@"NWPosition" fromDictionary:@{@"positionId": @"positionId", @"orgId": @"orgId", @"name": @"positionName"} withKey:@"positionId" andConnections:positionConnections] 
    method:RKRequestMethodAny pathPattern:@"api/positionservice/get" keyPath:nil statusCodes:statusCodes]]; 

// ... 

然後,我能夠做到簡單的請求,它的工作很好:

[manager postObject:nil path:@"api/shiftservice/get" parameters:@{@"workerIds": @[@1]} 
    success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 
    NSLog(@"Loaded shifts: %d", [[mappingResult array] count]); 
} failure:^(RKObjectRequestOperation *operation, NSError *error) { 
    NSLog(@"Failed to load shifts with error: %@", [error localizedDescription]); 
}]; 

注:這使用了一些輔助方法,其中我將在這裏重現:

- (RKConnectionDescription *)connectionForRelation:(NSString *)relation 
    localKey:(NSString *)localKey foreignKey:(NSString *)foreignKey 
    withRels:(NSDictionary *)rels 
{ 
    return [[RKConnectionDescription alloc] initWithRelationship:rels[relation] 
     attributes:@{localKey: foreignKey}]; 
} 

- (RKEntityMapping *)entityMappingForName:(NSString *)name 
    fromDictionary:(NSDictionary *)dict withKey:(NSString *)key 
{ 
    RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:name 
     inManagedObjectStore:[AppDelegate managedObjectStore]]; 
    [mapping addAttributeMappingsFromDictionary:dict]; 
    mapping.assignsDefaultValueForMissingAttributes = YES; 
    mapping.assignsNilForMissingRelationships = YES; 
    mapping.identificationAttributes = @[key]; 

    return mapping; 
} 

- (RKEntityMapping *)entityMappingForName:(NSString *)name 
    fromDictionary:(NSDictionary *)dict withKey:(NSString *)key 
    andConnections:(NSArray *)connections 
{ 
    RKEntityMapping *mapping = [self entityMappingForName:name 
     fromDictionary:dict withKey:key]; 
    for (RKConnectionDescription *connection in connections) 
    { 
     [mapping addConnection:connection]; 
    } 
    return mapping; 
} 
0

不是,但不應該設置反相關係。