2016-11-14 44 views
3

我有一个对象有很多狗的人。 App有单独的页面,它显示只是狗和其他的页面,它显示了人的狗领域 - 无法用现有的主键值创建对象

我的模型如下

class Person: Object { 
    dynamic var id = 0 
    let dogs= List<Dog>() 

    override static func primaryKey() -> String? { 
     return "id" 
    } 
} 

class Dog: Object { 
    dynamic var id = 0 
    dynamic var name = "" 

    override static func primaryKey() -> String? { 
     return "id" 
    } 
} 

我存储在境界的人。人有详细信息页面,我们可以获取并展示他的狗。如果狗已经存在,我更新该狗的最新信息并将其添加到人的狗列表中,否则创建新狗,保存并将其添加到人员列表中。这在coredata中有效。

// Fetch and parse dogs 
if let person = realm.objects(Person.self).filter("id =\(personID)").first { 
    for (_, dict): (String, JSON) in response { 
     // Create dog using the dict info,my custom init method 
     if let dog = Dog(dict: dict) { 
      try! realm.write { 
       // save it to realm 
       realm.create(Dog, value:dog, update: true) 
       // append dog to person 
       person.dogs.append(dog) 
      } 
     } 
    } 
    try! realm.write { 
     // save person 
     realm.create(Person.self, value: person, update: true) 
    } 
} 

在试图与他的狗,更新的人,境界抛出异常 不能与现有的主键值创建对象

+1

凡在'person.dogs.append(配方)的'recipe'值'是从哪里来的?这是不是很清楚你想在这里做什么,对不起! – TiM

+0

对不起,它一定是person.dogs.append(狗)。我只是创建/更新狗,并将其添加到人的狗@TiM –

+1

啊好吧。我想我现在看到这里发生了什么。我会添加一个答案。 :) – TiM

回答

18

这里的问题是,即使您正在创建一个全新的Realm Dog对象,实际上并没有将其保存到数据库中,因此当您调用append时,您试图添加第二个副本。

当你调用realm.create(Dog, value:dog, update: true),如果与ID对象在数据库中已存在,你只需更新现有的与你所创建的dog实例的值对象,但dog情况下仍然是一个独立的副本;它不是数据库中的Dog对象。您可以通过检查dog.realm是否等于nil来确认。

所以,当你调用person.dogs.append(dog),因为dog是不是已经在数据库中,域试图创建一个全新的数据库条目,但失败了,因为已经有与ID狗。

如果要将dog对象附加到person,则需要查询Realm以检索引用数据库中条目的正确dog对象。值得庆幸的是,这是与主键的支持,因为你可以使用Realm.object(ofType:forPrimaryKey:)方法领域对象非常简单:

if let person = realm.object(ofType: Person.self, forPrimaryKey: "id") { 
    for (_, dict): (String, JSON) in response { 
     //Create dog using the dict info,my custom init method 
     if let dog = Dog(dict: dict) 
     { 
      try! realm.write { 
       //save it to realm 
       realm.create(Dog, value: dog, update: true) 
       //get the dog reference from the database 
       let realmDog = realm.object(ofType: Dog.self, forPrimaryKey: "id") 
       //append dog to person 
       person.dogs.append(realmDog) 
      } 
     } 
    } 
    try! realm.write { 
     //save person 
     realm.create(person .self, value: collection, update: true) 
    } 
} 
+0

在我的情况下,我有6个事件来保存每个具有唯一类型。我将所有这6个事件保存在作业表中。但是,当我试图用不同的工作ID创建一个工作对象时,当我创建第一个事件杉木第二工作。我得到错误。不能使用相同的主键创建对象。 –

+0

如果必须,您可能需要查询数据库以查看是否存在具有相同主键的对象。只有当您尝试使用相同的主键添加第二个对象时才会出现该错误,因此您只需确保您的逻辑没有这样做。 :) – TiM