2016-11-14 46 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