我是CoreData的新手,因此我正在寻求一些帮助。
我有两个名为List(name:String)和Items(name:String,quantity:Int)的实体。它们具有一对多的关系,即List可以有很多项。它们背后的逻辑是用户可以使用他的首选项名称创建一个新的ListName并向其添加项目。
我目前有两个表视图控制器,一个用于向Items实体添加项目,另一个用于显示所有Lists实体以及该列表包含的任何项目。
我已经编写了将项目保存到项目数组中的代码,但我的问题是如何编写代码来实现关系,这样我就可以将[Items]保存在他们尊重的List中,所以当我加载时我的tableView中的总列表数量我可以查看它们。
例如List(名称:Test)将有Items(name:sometext,quantity:1)等。
答案 0 :(得分:1)
在我们实际讨论您的问题的解决方案之前,我认为您应该解决几个问题。
错误1:命名惯例
核心数据中的关系应该以这样的方式命名:当它们被放置在它们加入的两个实体的名称之间时,它们构成一个含义完整的句子。它使开发人员(将来无论谁维护)的生活变得简单。
因此,不要将列表和列表项之间的关系命名为listName,这没有多大意义,您应该考虑将其重命名为“Contains”。
列表 - >包含 - > listItems中。有道理???
错误2:
从列表到项目之间只创建一种关系,而不是从列表到列表创建反向关系可能有时会在将来导致不必要的代码,
for ex:假设您在特定列表中显示项目的详细信息,并且由于某种原因您想知道它属于哪个列表,如果您没有反向关系,则必须查询核心数据以查找哪个列表item属于并稍后获取它:)
相反,创建反向关系可以让您立即访问列表对象。
遵循早期提到的惯例,项目 - > belongsTo - >列表:))
建议:
仔细查看关系包含的是一对多,其中belongsTo是一对一的。这意味着列表可以包含许多项目,但项目只能属于一个列表:)
根据您的需要进行修改:)
让我们回答一下问题:)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.managedObjectContext.performAndWait {
let item1 = NSEntityDescription.insertNewObject(forEntityName: "Item", into: appDelegate.managedObjectContext) as! Item
item1.name = "abcd"
item1.quantity = 2
let item2 = NSEntityDescription.insertNewObject(forEntityName: "Item", into: appDelegate.managedObjectContext) as! Item
item2.name = "efgh"
item2.quantity = 5
let list = NSEntityDescription.insertNewObject(forEntityName: "List", into: appDelegate.managedObjectContext) as! List
list.name = "Test1"
list.contains = NSSet(array: [item1,item2])
//as an alternative you can save the list to item as well :)
//both will have same effect
item1.belongsTo = list
item2.belongsTo = list
try! appDelegate.managedObjectContext.save()
}
正如您在上面的代码中看到的那样,
我创建了item1和item2,因为我没有任何列表项我也创建了列表。如果您已经从核心数据中获取列表并使用它:)
list.contains = NSSet(array: [item1,item2])
上述声明确定了item1,item2和list :)之间的关系。
请注意::contains是一个集合,因此如果您只是将其设置为新值,u将会丢失所有现有关系,因此您应该将新项目附加到现有list.contains集合: )
在我的情况下,清单是新鲜的,因此只需将其设置为新值:)
item1.belongsTo = list
item2.belongsTo = list
如果上述语句执行相同的工作,在这里您不必担心更新列表的包含属性,它将由核心数据自动更新:)
希望有所帮助:)