【问题标题】:Core Data - Setting a Relationship核心数据 - 建立关系
【发布时间】:2010-08-01 20:42:45
【问题描述】:

我在使用 Core Data 时遇到了问题,这让我束手无策。所以我想知道你们中是否有任何优秀的人可以提供帮助。

基本上,我在一个 Core Data 项目中有两个实体。它们是:

作者 {authorName, dateOfBirth}
图书 {bookName, pages}

作者与书籍之间存在一对多的关系,称为“作者”,而反向关系称为“书籍”。我已经导出了这些实体的子类,并创建了我的 fetch 控制器。我现在是否必须以编程方式定义关系?

作者列表当前显示在我的表格视图中。目前,当我点击作者时,我只能显示我的 Core Data 项目中所有书籍的列表。我将如何访问特定作者的书籍列表?我假设我会使用 NSPredicate,到目前为止我的逻辑是:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY authors.bookName LIKE[cd] %@", authorName];

...但我很确定这是不正确的。

我已经在网上搜寻了几个小时以寻求答案,但仍然感到困惑。因此,我们将不胜感激。

非常感谢:)

【问题讨论】:

    标签: iphone core-data predicate relationship


    【解决方案1】:

    您可能有以下情况:

    @interface AuthorListController : UITableViewController {
        UITableView *table;
        NSArray *authors; // array of NSManagedObjects
    }
    
    @property (nonatomic, retain) IBOutlet UITableView *table;
    @property (nonatomic, retain) NSArray *authors;
    

    在你的实现中你有:

    -(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
        NSManagedObject *author = [authors objectAtIndex:indexPath.row];
        // create and show your book-level view here
    }
    

    现在您已经获得了选定的作者对象,您可以直接获得书籍(假设您已经在 Data Modeler 中设置了一对多关系):

    NSSet *books = author.books;
    

    但是,如果您没有加载作者对象,无论出于何种原因,您都可以构建一个新的搜索并在谓词中使用 books->authors 关系:

    NSManagedObjectContext *objectContext = self.managedObjectContext;
    NSEntityDescription *entity = [NSEntity entityForName:@"Books" inManagedObjectContext:objectContext];
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
    [fetch setEntity:entity];
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"author.name == %@", authorName];
    [fetch setPredicate:predicate];
    
    // ... create your error object and execute the fetch, etc
    

    【讨论】:

    • 我没有“作者”的 NSArray?我只是使用默认的导航控制器核心数据模板。另外,“author.name”是指“author.authorName”吗?我没有简单的“.name”。谢谢。
    • 我现在设法解决了这个问题。我使用了'authorName == %@", authorName'。感谢您的帮助!
    【解决方案2】:

    成员变量“books”存在于您的 Author 类中,并指向 NSManagedObject 记录的 NSSet,所有这些记录都是 Book 对象。

    显然,您可以获取作者对象,因此在给定作者对象的情况下获取该作者的书籍列表:

    NSManagedObject *author = [self getSelectedAuthor];
    NSSet *booksByAuthor = [author valueForKey:@"books"];
    NSArray *booksArray = [booksByAuthor allObjects]; 
    

    然后您可以使用 NSArray 来填充 UITableView。

    XCode 能够为您的核心数据实体自动创建托管对象类。打开您的 xcdatamodel 文件,选择实体之一,然后选择 File -> New。您应该看到托管对象类作为一个选项。这将允许您创建 Author 和 Book 类作为 NSManagedObject 的子类。这些类将实体的每个属性都定义为一个属性,这意味着上面的代码可以读取:

    Author *author = [self getSelectedAuthor];
    NSSet *booksByAuthor = author.books;
    NSArray *booksArray = [booksByAuthor allObjects];
    

    【讨论】:

    • 对不起,我不知道这对我有什么帮助。
    • 我是在细节视图控制器还是视图控制器中执行此操作?另外,“getSelecterAuthor”从何而来?
    • 不管我怎么尝试,使用你写的东西只会让我的应用崩溃。
    • 这将进入作者表视图委托的 tableView:didSelectRowAtIndexPath:。 getSelectedAuthor 是此示例中的伪代码抽象,用于获取用户选择的作者对象。您已经在某处拥有 Author 对象,否则您将无法填充作者 UITableView。 booksArray 应该交给您的详细信息表视图。
    • 感谢您的回复。我已经接受了您所说的内容,但是当我 NSLog 传递的 booksArray 时,它似乎为空“booksArray:()”我的 tableView 中有以下代码:didSelectRowAtIndexPath NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath] ;作者 *author = selectedObject; NSSet *booksByAuthor = author.books; NSArray *booksArray = [booksByAuthor allObjects]; myDetailViewController.booksArray = booksArray;但是就像我说的,传递的数组是空的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多