【问题标题】:Core Data Fetch One to Many Entity核心数据获取一对多实体
【发布时间】:2014-04-08 05:03:14
【问题描述】:

问题:

由于未捕获的异常“NSInvalidArgumentException”导致应用程序终止错误,原因:“此处不允许使用多对多键”。

我想获取 Section 和 News 实体中的所有属性。但是这些属性应该相互匹配。例如,假设我有一个栏目名称 =“yy”,其匹配的新闻是 title="sports" 和 title="daily news"。另一个部分名称 =“aa”,只有一个匹配的新闻标题,即 title = "Horoscopes" 等等...获取正确的部分属性及其正确的新闻属性(一个或多个)。

  1. 这是核心数据结构:

  1. 我有新闻和部分的实体类:(自动生成)

    //News.h:
    @class Section;
    @interface News : NSManagedObject
    
    @property (nonatomic, retain) NSNumber * id;
    @property (nonatomic, retain) NSString * updated;
    @property (nonatomic, retain) NSString * title;
    @property (nonatomic, retain) NSString * synopsis;
    @property (nonatomic, retain) NSString * pub_date;
    @property (nonatomic, retain) NSNumber * imageId;
    @property (nonatomic, retain) Section *sectionRelation;
    @end
    
    // News.m define those attribute as @dynamic
    
    // Section.h 
    @class News;
    @interface Section : NSManagedObject
    
    @property (nonatomic, retain) NSString * name;
    @property (nonatomic, retain) NSSet *newsRelation;
    @end
    
    @interface Section (CoreDataGeneratedAccessors)
    - (void)addNewsRelationObject:(News *)value;
    - (void)removeNewsRelationObject:(News *)value;
    - (void)addNewsRelation:(NSSet *)values;
    - (void)removeNewsRelation:(NSSet *)values;
    
    // section.m still @dynamic
    
  2. 我使用 NSDictionary 将值插入到这些实体中:

    -(Section*)insertSectionEntity:(NSDictionary*)values
    {
       Section* sectionObject = [NSEntityDescription     insertNewObjectForEntityForName:ENTITY_NEWS_SECTION inManagedObjectContext:[[CoreDataHelper  coreDataManager]managedObjectContext]];
       [sectionObject setValuesForKeysWithDictionary:values];
       // I did not use [section addNewsRelationObject:news]; I used in somewhere else.
       return sectionObject;
     }
    
     -(News*)insertNewsEntity:(NSDictionary*)values
    {
       News* newsObject = [NSEntityDescription insertNewObjectForEntityForName:ENTITY_NEWS inManagedObjectContext:[[CoreDataHelper coreDataManager]managedObjectContext]];
       [newsObject setValuesForKeysWithDictionary:values];
       return newsObject;
     }
    
  3. 这是我将两个实体存储到核心数据中的方式:

    // this array include the NSDictionary values of Section and News entity
    -(void)storeNewsAndSectionEntity:(NSMutableArray*)array
    {
       if(array.count!=0){
          News* news       = NULL;
          Section* section = NULL;
    
         // break into two different dictionaries and store in core data
         for (NSDictionary* dic in array) {
            // name is the attribute of section
            if([dic valueForKey:@"name"]!=nil){
                section = [self insertSectionEntity:dic];
             }
             else{
                news = [self insertNewsEntity:dic];
                [section addNewsRelationObject:news]; // generate relation
             }
          }
          [[CoreDataHelper coreDataManager]saveContext]; // save context
        }
    }
    
  4. 这是我获取所有实体属性的方式:

    -(NSArray*)fetchCoreDataNews:(Section*)section
    {
        if([[CoreDataHelper coreDataManager]isEntityExist:@"News"]){
    
         // fectch news in relation with that specific section
         NSArray* newsArray = [[CoreDataHelper coreDataManager]fectchEntityBaseOnPredicate:@"News" withPredicate:@"SUBQUERY(sectionRelation, $x, $x.newsRelation == %@).@count != 0" withObject:section];        
         return newsArray;
        }
        else
         return nil;
     }
    
    -(NSArray*)fetchCoreDataSection
    {
       if([[CoreDataHelper coreDataManager]isEntityExist:@"Section"]){
           NSArray* sectionArray = [[CoreDataHelper coreDataManager]fectchAllAttributesFromEntity:@"Section"];
           return sectionArray;
       }
       else
         return nil;
    }
    
     // I think this causing the problem:  Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'to-many key not allowed here'
     -(NSArray*)fectchEntityBaseOnPredicate:(NSString*)entityName withPredicate: (NSString*)predicateString withObject:(id)ManagedObject
     {
    
       NSManagedObjectContext *managedObjectContent = [[CoreDataHelper coreDataManager] managedObjectContext];
       NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
       NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContent];
    
       NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString, ManagedObject];
       [fetchRequest setPredicate:predicate];
       [fetchRequest setEntity:entity];
       NSArray* fectechedElements = [managedObjectContent executeFetchRequest:fetchRequest error:nil]; // SELECT
       return fectechedElements;
      }
    

谢谢!!

【问题讨论】:

  • 您能描述一下您的问题是什么以及您要做什么吗?真的很短的一句话?
  • 我想获取 Section 实体和 News 实体中的所有属性。但是现在,它给了我错误说“不允许使用多键”
  • @Marc Mosby 我已经编辑了问题。提前致谢。 :)

标签: ios objective-c core-data nspredicate


【解决方案1】:

其实我们可以通过 ValueForKey 轻松获取一对多的属性。

// get section entity
_sectionArray = [[[CoreDataControl initCoreDataControl]fetchCoreDataSection]mutableCopy];

// call relation name of each section
NSSet *news = [[_sectionArray objectAtIndex:0] valueForKey:@"newsRelation"];    

// get all related news entities in the parents entity
NSArray* allObjects = [news allObjects];

// then you can call each specific attribute in that entity
[[allObjects objectAtIndex:0]valueForKey:@"title"]; // it will return the attribute.... :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 2021-06-10
    相关资源
    最近更新 更多