2016-08-05 97 views
1

我在我的代碼中有主鍵的CatalogItem對象。 境界是在下面的代碼寫入工作時拋出一個錯誤:將現有對象追加到領域列表

class CartItem: Object { 
    dynamic var id: Int = 0 
    dynamic var item: CatalogItem! 
    dynamic var amount: Int = 0 

    convenience required init(id: Int, item: CatalogItem, amount: Int) { 
     self.init() 
     self.id = id 
     self.item = item 
     self.amount = amount 
    } 
} 

class Cart: Object { 

    var items = List<CartItem>() 

    func addItem(item: CatalogItem) { 
     let realm = try! Realm() 
     let newItem = CartItem(id: item.id, item: item, amount: 1) 
     do { 
      try realm.write { 
       items.append(newItem) 
      } 
     } catch let e { 
      handleError(e) 
     } 
    } 
} 

錯誤:

'RLMException', reason: 'Can't set primary key property 'id' to existing value '352'.' 

我希望境界引用現有CatalogItem但它看起來像它試圖再添一個。 有沒有辦法實現這種關係? 注意:所有對象都存儲在一個領域。

+0

那麼,我不創建另一個對象,我參考現有的一個。 我的意思是,'CartItem'完全沒有主鍵。只有它引用的元素 - 「CatalogItem」有一個。但是我沒有在任何地方調用'CatalogItem.init()',爲什麼它又被創建了? – charlag

+0

是的,你是對的,它不是一個dup,但答案是幾乎相同的,你不能有兩個對象具有相同的主鍵 – Idan

+0

讓我把這樣的問題:當我創建'CartItem'並通過' CatalogItem',Realm會嘗試創建另一個'CatalogItem'? – charlag

回答

1

由於jpsim指出,問題是,我嘗試非託管對象追加到境界,並有與數據庫相同主鍵的對象。 我必須以不同的方式解決問題,因爲建議的解決方案會擦除存在於領域中的對象的屬性。

func addItem(item: CatalogItem) { 
    let realm = try! Realm() 
    var catalogItem = item 
    if item.realm == nil, 
     let foundItem = realm.objects(CatalogItem) 
      .filter("id == %@", item.id).first { 
     catalogItem = foundItem 
    } 
    let newItem = CartItem(id: item.id, item: catalogItem, amount: 1) 
    do { 
     try realm.write { 
      items.append(newItem) 
     } 
    } catch let e { 
     handleError(e) 
    } 
} 
2

如果將非託管Realm對象附加到託管List,則將創建該非託管對象。但是,使用現有主鍵創建對象是錯誤的。你可以使用Realm.add(_:update: true)指定你想創建的對象,如果它不存在,否則用你傳入的新值更新現有對象的屬性。

所以我想你想讓你的addItem()函數是這樣的:

func addItem(item: CatalogItem) { 
    let realm = try! Realm() 
    let newItem = CartItem(id: item.id, item: item, amount: 1) 
    do { 
     try realm.write { 
      realm.add(newItem, update: true) 
      items.append(newItem) 
     } 
    } catch let e { 
     handleError(e) 
    } 
} 
+0

謝謝!那就是我的問題,但我必須以不同的方式解決問題。 – charlag