保存到多个实体

时间:2015-09-30 18:13:35

标签: ios objective-c core-data

对于详细视图,我想让用户为每个项目留言。该应用程序适用于数据驱动的网站。在Web版本中,Web应用程序将注释存储在单独的表中,其中包含itemid的字段。

在核心数据中,我有一个项目实体和另一个注释实体。 notes实体有一个名为itemid的属性。当用户第一次创建便笺时,它会将itemid存储在便笺记录中。

我的问题是当你拉出项目进行编辑时,如何根据具有某个itemid的音符同时拉出正确的音符?

在数据库情况下,你可以进行连接,或者从网页中你可以对两个表做出两个单独的请求,但我对如何使用Core Data执行此操作感到有些不知所措。

你是否必须在笔记中建立关系,因此在项目行中有noteid

如果是这样,您可以使用项目对象访问note属性吗?

提前感谢任何建议。

这就是我用来保存信息的方法。我只是不知道如何确保我将它保存为正确的音符。

self.managedObjectContext = [IDModel sharedInstance].managedObjectContext;
NSString *noteText = _notesView.text;
NSNumber *itemId = self.item.itemid;
// Populate Record
[self.note setValue:noteText forKey:@"note"];
[self.note setValue:itemId forKey:@"itemid"];

Model (simplified):

Item:
name NSString
itemid: Integer 64

Note:
note NSString
noteid: Integer 64
itemid: Integer 64

  Edit:

尝试在创建两者时链接注释和项目的代码...

//in save method
        // Create Entity
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Notes" inManagedObjectContext:self.managedObjectContext];

        // Initialize New Record ie newNote
        NSManagedObject *record = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];

        // Populate Record
        [record setValue:note forKey:@"note"];
        [record setValue:localid forKey:@"localnid"];

        // Save Record
        NSError *error = nil;

        if ([self.managedObjectContext save:&error]) {
//   If note saved, save new item…
             if (itemlength>1) {
            Items *newItem = [NSEntityDescription insertNewObjectForEntityForName:@“Item” inManagedObjectContext:self.managedObjectContext];
            newItem.item = item;
              newItem.note = self.note
//This is null as note does not seem to pick up newly created note.
            if (![self.managedObjectContext save:&error]) {
                NSLog(@"Error: %@", [error localizedDescription]);
             }
             }

2 个答案:

答案 0 :(得分:1)

是的,您应该使用ItemNote实体之间的关系。要创建关系,只需在数据模型编辑器中从一个实体按Ctrl键拖动到另一个实体。请注意,Xcode会自动添加反比关系:

Screenshot of ERD

为了清楚起见,我重新命名了这些关系 - 您可以在右侧面板中定制关系的详细信息(名称,一对一v,删除规则等)。在上面的示例中,Item实体有三个属性:2个属性和1个关系。给定Item个对象,比如myItem,可以使用键值编码方法访问这些属性的值:valueForKey:setValue:forKey:。例如,如果将attribute定义为字符串:

 NSString *myStringValue = [myItem valueForKey:@"attribute"];
 [myItem setValue:@"new value for attribute" forKey:@"attribute"];

那是非常啰嗦的。因此,为了简化生活,请使用“创建NSManagedObject子类...”选项。 Xcode将每个实体配置为NSManagedObject的子类,并将创建具有属性详细信息的新类文件(.h / .m或.swift)。对于示例Item

@property (nullable, nonatomic, retain) NSString *attribute;
@property (nullable, nonatomic, retain) NSString *attribute1;
@property (nullable, nonatomic, retain) Note *note;

要意识到的是note关系是注意。您必须使用它来查找相应的Note对象,这不是外键或noteid。 是Note对象。在引擎盖下,CoreData正在为基础表添加主键和外键,但所有这些恶化都被抽象掉了。

创建子类后,可以使用点访问器作为对象属性:

NSString *myStringValue = myItem.attribute;
myItem.attribute = @"new value for attribute"; 

对于关系,如果您有一个名为Item的{​​{1}}对象和一个名为myItem的{​​{1}}对象,则可以将关系值设置为:

Note

或等效地:

myNote

(注意:使用其中一个,而不是两个; CoreData会自动为您设置反向关系。)

现在,您已经添加了Web服务器的复杂功能,从中下载了Item对象和Note对象。在您的Web服务器上,myItem.note = myNote; 表有一个myNote.item = myItem; 字段,用于链接Items和Notes。在某些时候,您希望使用itemid链接Note对象和Item对象。通常的方法是执行一次(一旦CoreData对象从服务器同步),相应地设置关系,然后使用关系而不是itemid来获取给定项目的注释。例如,如果要创建新的Notes对象,并且服务器中的itemid为“1234”,则可以执行以下操作:

itemid

然后,只要您拥有特定的Item对象,就可以使用

访问相应的注释
Note

此外,您可以级联点符号,因此为myItem的Note获取NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Item"]; fetchRequest.predicate = [NSPredicate predicateWithFormat:@"itemid == %@", @"1234"]; NSError *error; NSArray *results = [context executeFetchRequest:fetchRequest error:&error]; // should check for nil results/error if (results.count > 0) { // found (at least) one Item with itemid == @"1234" // use the first to set the relationship newNote.item = results[0]; } 的值,使用:

Note *myNote = myItem.note;

修改

您的保存方法非常接近:要么在保存之前设置attribute,要么使用NSString *noteText = myItem.note.attribute;

self.note = record

答案 1 :(得分:0)

要实现目标,您需要创建#include <array> #include <vector> #include <utility> template <typename T, std::size_t N> class A { public: A(int a, int b) : A(a, b, std::make_index_sequence<N>{}) { } private: template <std::size_t... Is> A(int a, int b, std::index_sequence<Is...>) : data_{ { std::vector<T>(((void)Is, a + b))... } } { } std::array<std::vector<T>, N> data_; }; 向右传递NSFetchRequest

将针对您的NSPredicate实体运行获取请求。谓词将允许您指定要检索的Note对象是特定Note的对象。

因此,如果noteidItem之间存在一对一关系,则Note应如下所示:

NSPredicate

这里我假设你在两个实体之间创建了一个关系,否则你需要手动完成。你能提供模型的样子吗?