【问题标题】:Core Data - how to initialize entity which has relationship with another entity from CSV file?核心数据 - 如何初始化与 CSV 文件中的另一个实体有关系的实体?
【发布时间】:2014-01-29 06:55:19
【问题描述】:

在 Core Data 中,您可以使用 NSEntityDescription 类的 insertNewObject: inManagedContext: 方法初始化实体。但是,如何初始化与另一个实体有关系的实体?

所以在以下两个 CSV 文件中:


1, Mike, CA
2, Robinson, MA
3, Peter, CA
4, Bob, NZ

1, 2, 20
2, 2, 23
3, 2, 22
4, 1, 32

我要连接的是两个文件的第一列(在这种情况下是一对一的关系)。

我想出了一个想法,您首先循环遍历第一个文件的每一行,然后循环遍历第二个文件的每一行,并且仅当这两行的第一个数字相互匹配时才创建新实体 -并在不是时跳到下一个迭代。但是,当我尝试连接两个以上的文件时,此解决方案要么计算量大,要么相当复杂 - 例如,如果我想连接六个文件并且每个文件有 3,000 行,我必须检查条件 3,000^6 次。

那么这是进行初始化的更好方法吗?由于某些原因,到目前为止我读过的每个在其实体中使用关系的示例都已经完成了这些初始化并且只是直接使用了 SQLite 数据库 - 所以也许不可能从代码中进行初始化,我应该做的是首先存储那些 CSV数据到 SQLite 数据库中,然后将数据库复制并粘贴(或一些类似的方式)到我的项目中?

我也不知道为什么this answer 说我不必初始化关系部分 - 当我跳过关系属性(并向那些没有关系的属性插入任何值)时,插入不返回任何错误。但是,它存储在 nil 到,所以我根本无法在我的代码中连接这两个实体,对吧?

我使用 iOS 7 和 Xcode 5。

[更新]

假设 file1 和 file2 都由 NSString 组成:


for (NSString *row in file1) {
    NSArray *line = [row componentsSepareatedByString:@","];
    File1Entity *file1entity = [NSEntityDescription insertNewObjectForEntityForName:@"File1Entity" inManagedObjectContext:_managedObjectContext];
    for (NSString *row2 in file2) {
        NSArray2 *line2 = [row2 componentsSeparatedByString:@","];
        if (line[0] isEqualToString: line2[0]) {
            File2Entity *file2entity = [NSEntityDescription insertNewObjectForEntityForName:@"File2Entity" inManagedObjectContext:_managedObjectContext];
            file1entity.name = line[1]
            file1entity.residence = line[2]
            file2entity.number = line2[1]
            file2entity.age = line2[2]
            file1entity.n = file2entity
            NSError *err;
            [_managedObjectContext save:&err];
        }
   }

file1的列是nnameresidence,分别是NSNumberNSStringNSString

file2的列是nnumberage,都是NSNumber

我想将n 连接为关系。那么我必须在这里迭代整行吗? (其实我意识到这种情况不需要迭代整个部分;因为这是一对一的关系,我可以在检测到匹配的对象时终止外部迭代。但它仍然必须一直迭代每当我想使用一对多或多对多关系时,不是吗?

【问题讨论】:

    标签: ios objective-c core-data


    【解决方案1】:

    关系实际上只是另一个访问者。你set这两个实体的关系。 Core Data 负责其余的工作。

    假设您有一个名为 Person 的实体和另一个名为 Address 的实体。这些实体有一个关系称为address 从个人到地址和address 从地址到个人。您可以通过以下方式设置它们之间的关系:

    Person *person = ...;
    Address *address = ...;
    [person setValue:address forKey:@"address"];
    

    该示例使用 KVC(键值编码)。如果您创建了子类并定义了属性,您也可以这样做:

    Person *person = ...;
    Address *address = ...;
    [person setAddress:address];
    

    反向关系(地址到人员)由 Core Data 自动管理,因此您无需设置反向关系。

    至于何时设置这种关系,这完全取决于您和您的应用程序的设计。

    更新

    您的示例文件不是代码,所以不,我不能使用它们。发布代码,我们可以进一步讨论这方面。

    ... 是您放置已经知道如何操作的代码的地方。创建实体。我发布的示例向您展示了如何设置您所询问的关系

    更新 2

    有问题的行应该是:

    file1entity.n = file2entity;
    

    您正在将file1entity 上的n 的关系设置为file2entity 的实例。它只是另一个属性访问器,应该被同等对待。

    请记住,Core Data 首先是一个对象图。将其及其关系视为对象图。

    【讨论】:

    • 我不确定我能理解你的意思 - 这不是我尝试使用循环做的,对吧?我也不知道你在... 中的意思。您能否使用我的两个示例文件向我展示一个示例(请随意命名列)?
    • 啊,我知道我不应该将两个 n 属性相互连接 - 现在修复了我的原始代码。然后回到我原来的问题:is it better way to make an initialization? 还是我总是要用那些嵌套循环来初始化它?
    • 您可以考虑将对象存储在以标识符为键的字典中,然后在字典中查找。这将删除嵌套循环。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 2013-10-18
    相关资源
    最近更新 更多