核心数据关系无返回值

Posted

技术标签:

【中文标题】核心数据关系无返回值【英文标题】:Core data relationship returning no value 【发布时间】:2013-12-03 09:22:51 【问题描述】:

我有 2 个带有 Driver 和 Work_Shift 的实体。 Driver 与 Work_Shift 是一对多的关系,Work_SHift 与 Driver 是一对一的关系。

我在获取 Work_shift 数据时尝试获取驱动程序详细信息,但我得到的是空值。

这是我的代码:

这是获取 Work_Shift 详细信息及其内部关系的代码。

NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"Work_Shift"];

    //[fetch setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"work_shifts.id"]];

    fetch.returnsObjectsAsFaults = NO;

    work_shift_results = [[self managedObjectContext] executeFetchRequest:fetch error:&error];

    if([work_shift_results count]>0)
    
        Work_Shift *shift = [work_shift_results objectAtIndex:0];
        NSSet *driverSet = shift.work_shifts;
        NSArray *driverArray = [driverSet allObjects];

        NSLog(@"Shift: %@",shift);
    

这是我得到的输出

<Work_Shift: 0x15678540> (entity: Work_Shift; id: 0x15665460 <x-coredata://7059F32C-63F0-4B2C-A104-5FA339AE2473/Work_Shift/p2> ; data: 
    block = nil;
    "dest_mine_loc_id" = 0;
    "driver_id" = 6;
    "end_date" = nil;
    weight = 0;
    "work_shifts" =     (
    );
)

我已经检查过了,Driver 表中有条目。我也尝试取消注释上面的代码,仍然得到相同的结果。

实体是

@class Work_Shift;

@interface Driver : NSManagedObject

@property (nonatomic, retain) NSString * address;
@property (nonatomic, retain) NSString * contact_number;
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSNumber * is_active;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) Work_Shift *driver;

@end

@class Driver;

@interface Work_Shift : NSManagedObject

@property (nonatomic, retain) NSString * block;
@property (nonatomic, retain) NSNumber * dest_mine_loc_id;
@property (nonatomic, retain) NSNumber * driver_id;
@property (nonatomic, retain) NSDate * end_date;
@property (nonatomic, retain) NSNumber * excavator_id;
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSNumber * material_type_id;
@property (nonatomic, retain) NSNumber * mine_location_id;
@property (nonatomic, retain) NSNumber * relative_level_id;
@property (nonatomic, retain) NSNumber * shift_type_id;
@property (nonatomic, retain) NSDate * start_date;
@property (nonatomic, retain) NSNumber * truck_type_id;
@property (nonatomic, retain) NSNumber * weight;
@property (nonatomic, retain) NSSet *work_shifts;
@end

@interface Work_Shift (CoreDataGeneratedAccessors)

- (void)addWork_shiftsObject:(Driver *)value;
- (void)removeWork_shiftsObject:(Driver *)value;
- (void)addWork_shifts:(NSSet *)values;
- (void)removeWork_shifts:(NSSet *)values;

@end

我错过了什么吗?

【问题讨论】:

Work_shift 和 Driver 关联的代码在哪里? 我已经使用 NSManagedObject 类创建了实体,我不确定这里的关联是什么意思.. :| 发布实体关系的详细信息。似乎您正在使用外键将驱动程序与工作班次相关联。通常最好直接关联对象。 Workshift.driver = 司机。 @DuncanGroenewald:用实体编辑了我的问题 好的,所以每个班次都属于一个司机。无需使用 driverID,只需在 Workshift 上创建一个属性 DRIVER *driver。然后创建一个workshift对象和一个driver对象并设置workshift.driver=driver. 【参考方案1】:

承诺的更好的例子

显示关系的模型

实体属性和关系

用于创建实体并设置属性和关系的示例代码。如果需要,我可以通过电子邮件将示例应用程序发送给您。

- (void)addEntities 

    Driver *driver1 = (Driver *)[self createNewDriverMethod1:@"Driver 1" address:@"Address 1"];
    Driver *driver2 = [self createNewDriverMethod2:@"Driver 2" address:@"Address 2"];

    Excavator *excavator1 = [self createNewExcavator:@"EXC001" make:@"CAT" model:@"DX1000"];
    Excavator *excavator2 = [self createNewExcavator:@"EXC002" make:@"CAT" model:@"DX2000"];

    // Current date as shift start date & time
    NSDate *shiftStartDate = [NSDate date];

    Workshift *workshift1 = [self createNewWorkshift:shiftStartDate hours:8.0 driver:driver1];
    workshift1.excavator = excavator1;


    Workshift *workshift2 = [self createNewWorkshift:shiftStartDate hours:8.0 driver:driver2];
    workshift2.excavator = excavator2;

    NSError *error;

    if (![[self managedObjectContext] save:&error]) 
        NSLog(@" error saving data %@, %@", error, error.userInfo);
    

    [self listWorkShifts];



- (void)listWorkShifts 

    NSFetchRequest *req = [[NSFetchRequest alloc] init];

    [req setEntity:[NSEntityDescription entityForName:@"Driver" inManagedObjectContext:[self managedObjectContext]]];

    NSError *error;

    NSArray *result = [[self managedObjectContext] executeFetchRequest:req error:&error];

    if (result == nil) 
        NSLog(@" error fetching Driver list %@", error);
        return;
    

    for (Driver *driver in result) 
        NSLog(@" Driver: %@", driver.name);


        for (Workshift *shift in driver.workshifts) 

            NSLog(@"   SHIFT");
            NSLog(@"         Start: %@", [shift.startDate description]); // Get date back as string
            NSLog(@"           End: %@", [shift.endDate description]); // Get date back as string
            NSLog(@"     Excavator: %@, %@", shift.excavator.make, shift.excavator.model);
            NSLog(@"   ");

        
        NSLog(@"   ");
    

- (NSManagedObject *)createNewDriverMethod1:(NSString *)name address:(NSString *)address

    NSManagedObject *newDriver = [NSEntityDescription
                                  insertNewObjectForEntityForName:@"Driver"
                                  inManagedObjectContext:[self managedObjectContext]];

    [newDriver setValue:name forKey:@"name"];
    [newDriver setValue:address forKey:@"address"];

    return newDriver;


- (Driver *)createNewDriverMethod2:(NSString *)name address:(NSString *)address

    Driver *newDriver = [NSEntityDescription
                               insertNewObjectForEntityForName:@"Driver"
                               inManagedObjectContext:[self managedObjectContext]];
    newDriver.name = name;
    newDriver.address = address;
    return newDriver;

- (Workshift *)createNewWorkshift:(NSDate *)startDate hours:(float)hours driver:(Driver *)driver

    Workshift *newWorkshift = [NSEntityDescription
                         insertNewObjectForEntityForName:@"Workshift"
                         inManagedObjectContext:[self managedObjectContext]];

    [newWorkshift setValue:startDate forKey:@"startDate"];

    // time interval in seconds
    NSTimeInterval interval = hours * 60 * 60;

    NSDate *endDate = [startDate dateByAddingTimeInterval:interval];

    [newWorkshift setValue:endDate forKey:@"endDate"];
    [newWorkshift setValue:driver forKey:@"driver"];

    return newWorkshift;

- (Excavator *)createNewExcavator:(NSString *)identifier make:(NSString *)make model:(NSString *)model

    Excavator *newExcavator = [NSEntityDescription
                               insertNewObjectForEntityForName:@"Excavator"
                               inManagedObjectContext:[self managedObjectContext]];

    [newExcavator setValue:identifier forKey:@"identifier"];
    [newExcavator setValue:make forKey:@"make"];
    [newExcavator setValue:model forKey:@"model"];

    return newExcavator;

【讨论】:

以上是关于核心数据关系无返回值的主要内容,如果未能解决你的问题,请参考以下文章

Android——关于Activity跳转的返回(无返回值和有返回值)——无返回值

函数参数,返回值,递归函数

Android——关于Activity跳转的返回(无返回值和有返回值)——有返回值

07_函数进阶

核心数据值返回 Nil

函数进阶