与 NSfetchedresultscontroller 的一对多关系

Posted

技术标签:

【中文标题】与 NSfetchedresultscontroller 的一对多关系【英文标题】:One to many relationship with NSfetchedresultscontroller 【发布时间】:2016-07-21 12:21:43 【问题描述】:

我在从一对多关系中获取对象时遇到问题。 我有两个实体“Featured”和“Event”,Featured 对象包含 featuresEvents 的属性,这是一对多关系,一个“Featured”项目到多个“Events”。

现在我需要使用 NSFetchedResultsController 来返回“featuredEvents”关系中的事件。我正在使用以下代码:

 NSFetchedResultsController *fetchedFeaturedEvents;
    NSFetchRequest *fetchRequest;
    NSError *error = nil;

    fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"SDMFeaturedEvent"];
    [fetchRequest setSortDescriptors:@[]];

    fetchedFeaturedEvents = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:theManagedObjectContext sectionNameKeyPath:nil cacheName:nil];
    [fetchedFeaturedEvents performFetch:&error];

    if (error) 
        NSLog(@"Unable to perform fetch.");
        NSLog(@"%@, %@", error, error.localizedDescription);
    

    return fetchedFeaturedEvents;

这很好,我返回了特色事件,但我还希望添加一个谓词以仅返回“featuredEvents”属性中的事件。所以问题是我如何创建谓词?

我基本上需要“精选”对象的 featuresEvents 属性中的所有“事件”,这可能吗?

【问题讨论】:

featuredEvents 属性已经为您提供了该功能的所有事件。访问该属性会自动导致故障触发并加载事件 - 无需查询事件。不确定我是否理解您的问题。 是的,我可以通过这种方式访问​​它们,但是是否可以通过谓词访问它们,因为我想在它们上运行其他谓词方法? 创建一个过滤特征反向关系的谓词。对于语法,请查看通过 Google 获得的无数示例和操作方法。 顺便说一句,您确实应该有一个排序描述符,否则 FRC 将在上下文更新时确定更改时遇到问题。 嗨,Avi,我试过这个:[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"SDMEvent IN featuresEvents"]];但是我遇到了以下问题:NSInvalidArgument(LHS 和 RHS 都是关键路径)一旦我让它工作,我会给它一个排序描述符。 【参考方案1】:

对于那些一直有类似问题的人,我最终使用了这种方法:

NSFetchRequest *fetchRequest;
    NSError *error = nil;
    NSArray *fetchedObjects;
    NSPredicate *soldOutPredicate;
    NSPredicate *criteriaMatchPredicate;
    NSCompoundPredicate *fullPredicate;
    NSSortDescriptor *usesDescriptor = [[NSSortDescriptor alloc] initWithKey:@"eventDate" ascending:YES];

    fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"FeaturedEvent"];
    [fetchRequest setSortDescriptors:@[]];
    fetchedObjects = [theManagedObjectContext executeFetchRequest:fetchRequest error:&error];

    if (error) 
        NSLog(@"Unable to perform fetch.");
        NSLog(@"%@, %@", error, error.localizedDescription);
    

    if ([[NSSDMUserDetails sharedManager]showsCriteraMatchEvents]) 

        if ([[NSSDMUserDetails sharedManager]isUserMale]) 
            criteriaMatchPredicate = [NSPredicate predicateWithFormat:@"(eventAgeMaleMin <= %@) AND (eventAgeMaleMax >= %@)",[[[NSSUserDetails sharedManager]userAge]stringValue],[[[NSUserDetails sharedManager]userAge]stringValue]];
        
        else
            criteriaMatchPredicate = [NSPredicate predicateWithFormat:@"(eventAgeFemaleMin <= %@) AND (eventAgeFemaleMax >= %@)",[[[NSUserDetails sharedManager]userAge]stringValue],[[[NSUserDetails sharedManager]userAge]stringValue]];
        

        fullPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[criteriaMatchPredicate]];

    

    if (![[NSSDMUserDetails sharedManager]showsSoldOutEvents]) 

        if ([[NSSDMUserDetails sharedManager]isUserMale]) 
            soldOutPredicate = [NSPredicate predicateWithFormat:@"eventPlacesMale == %@ || eventPlacesMale != %@",@"in stock",@"0"];
        
        else
            soldOutPredicate = [NSPredicate predicateWithFormat:@"eventPlacesFemale == %@ || eventPlacesFemale != %@",@"in stock",@"0"];
        

        fullPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[soldOutPredicate]];
    

    if (soldOutPredicate && criteriaMatchPredicate) 

        fullPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[soldOutPredicate,criteriaMatchPredicate]];

    

    if (fetchedObjects && fetchedObjects.count > 0) 

        SDMFeaturedEvent *feat = [fetchedObjects objectAtIndex:0];
        NSLog(@"All featured events %@",feat.featuredEvents);
        if (fullPredicate) 
            return [[feat.featuredEvents.allObjects filteredArrayUsingPredicate:fullPredicate]sortedArrayUsingDescriptors:@[usesDescriptor]];
        
        else if (![[NSSDMUserDetails sharedManager]showsCriteraMatchEvents])
            return [feat.featuredEvents.allObjects sortedArrayUsingDescriptors:@[usesDescriptor]];
        
        else
            return [NSArray new];
        

    
    return [NSArray new];

诀窍是从featuredEvent“featuredEvents”属性返回一个事件数组,然后您可以运行filteredArrayUsingPredicate 和sortedArrayUsingDescriptor 方法来根据您的要求对数组中的事件对象进行排序。当然,这不会返回 NSFetchedResultsController ,但这对于过滤非常有用。

【讨论】:

以上是关于与 NSfetchedresultscontroller 的一对多关系的主要内容,如果未能解决你的问题,请参考以下文章

CoreData、NSFetchedResultsController 和 performFetch:

LDAP 与 MYSQL .. JA-SIG CAS 与 LDAP 与 CAS 与 MySQL

python网络编程基础(线程与进程并行与并发同步与异步)

=与==&与&&| 与 || 的区别

与 0 进行比较与与某个值进行比较是不是更快?

三.工具与市场-债券与债务股票与公司