对象之间的核心数据关系

Posted

技术标签:

【中文标题】对象之间的核心数据关系【英文标题】:Core Data Relation between Objects 【发布时间】:2014-08-27 13:07:10 【问题描述】:

我有一个关于如何在 Core Data 中创建 2 个 NSObject 之间的关系的问题。

首先我有这个 CoreData 结构。

文件和表单之间存在关系。一个表格可以有多个文件,但一个文件只能有一个表格。

我只用 Swift 创建了 NSObjects(所以没有桥接头) - 现在有 2 个核心数据 NSObject 类:

class Forms: NSManagedObject 

@NSManaged var uuid: String
@NSManaged var damagenumber: String
@NSManaged var internalnumber: String
@NSManaged var date: NSDate
@NSManaged var name: String
@NSManaged var street: String
@NSManaged var postalcode: String
@NSManaged var city: String
@NSManaged var country: String
@NSManaged var templateJSON: String
@NSManaged var formname: String
@NSManaged var files: NSSet



class Files: NSManagedObject 

@NSManaged var url: String
@NSManaged var forms: Forms


我的文件作为 NSSet 在这里。

所以,我想例如添加一个包含 5 个文件的表单。所以从这样的开始:

var request = NSFetchRequest(entityName: "Forms")
request.returnsObjectsAsFaults = false;

let newFormObject = NSEntityDescription.insertNewObjectForEntityForName("Forms", inManagedObjectContext: context) as Forms

newFormObject.setValue(uuid, forKey: "uuid")
......

// 插入文件

 for index in 0...4 

     var request = NSFetchRequest(entityName: "Files")
     request.returnsObjectsAsFaults = false;

     let newFileObject = NSEntityDescription.insertNewObjectForEntityForName("Files", inManagedObjectContext: context) as Files
     newFileObject.setValue(arrFiles[index], forKey: "url")


好的,一切正常。但是:我如何连接这 2 个对象?如果您使用 Obj-C NSObjects 而不是 Swift,我有一些方法可以将文件添加到表单。但是我怎样才能只在 Swift 中做到这一点呢?

如果我有关系 - 我如何从某个表单中读取所有文件对象?

编辑:

我现在改行了:

@NSManaged var files: NSSet

@NSManaged var files: [Files]

并在循环中使用:

newFormObject.files.append(newFileObject)

这给我带来了以下错误:

*** 错误:这个进程调用了一个 NSArray-takeing 方法,例如 initWithArray:,并传入了一个 NSSet 对象。目前正在解决此问题,但很快就会让您感到悲伤。

【问题讨论】:

【参考方案1】:

减少您的代码:仅在您需要检索对象时设置 NSFetchRequests。因此,每次创建新对象时都不需要以下行:

//Forms
var request = NSFetchRequest(entityName: "Forms")
request.returnsObjectsAsFaults = false;

//Files
var request = NSFetchRequest(entityName: "Files")
request.returnsObjectsAsFaults = false;

保持一致:您已经设置了 NSManagedObject 子类。所以使用它们,不要使用键值编码。替换:

newFormObject.setValue(uuid, forKey: "uuid")

与:

newFormObject.uuid = uuid

问题:

如何连接这 2 个对象?

在循环结束时一行代码就足够了:

newFileObject.forms = newFormObject // where forms is the name of your relationship

问题:

我如何从某个表单中读取所有文件对象

当您需要检索某个 FormFiles objects 时,您可以执行 NSFetchRequest(允许您设置谓词、排序等等),或者您可以像这样简单地获取所有相关对象的 NSSet :

    //Get all Files objects (of a to-many relationship) related to a single Form object
    let filesSet = myForm.files as NSSet //where myForm is a Form managedObject
    let filesArray = filesSet.allObjects as Array

    for obj in filesArray as [Files] 
        println(obj.url)
    

【讨论】:

感谢您的回复:如果我使用:newFormObject.files = newFileObject 编译器告诉我:文件不可转换为 NSSet 因此将我的 NSSet 更改为 [Files] - 但现在:“文件与 Anyobject 不同” newFileObject.forms = newFormObject; 不要改变你的 NSManagedObject 子类。它们在您帖子的开头看起来很好。删除其中的 NSSet 会破坏您的核心数据。 尝试删除您的应用并重建它。每次更改 NSManagedObject 子类时,您的应用都必须符合新的核心数据模型。

以上是关于对象之间的核心数据关系的主要内容,如果未能解决你的问题,请参考以下文章

RestKit、核心数据和关系问题。父对象不识别子集

在核心数据一对多关系中多次使用同一个对象

如何为对象计数多个关系创建谓词?核心数据 iOS Swift

核心数据 - 具有一对多关系的实体正在检索除“关系”实体之外的所有实体对象的属性

使用 NSPredicate 过滤核心数据中的对象

映射核心数据关系的正确方法