2016-08-05 51 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