一对多关系 setter
One To Many Relationship setter
这是我第一次在 swift 中使用核心数据。我真的很喜欢它,但确保我的 Appdelegate 保存等也是一个挑战
问题
基本上我正在创建一个预算应用程序。预算结束后,我需要获取当前预算并将其存储到历史实体中。现在我有 2 个不同的实体在这里工作:
NewBudgetCreateMO 和 HistoryBudgetHolderMO。应该发生的是 HistoryBudgetHolder 应该将预算 (newBudgetCreateMO) 添加到它的一对多关系中。这是我的图表及其关系的图像。
现在,如果我设置正确,我应该允许在我的历史记录中添加任意数量的 NewBudgetCreateMO?下面的代码是为我的历史实体生成的代码,它显示它包含一个 NSSet
extension HistoryBudgetHolderMO {
@nonobjc public class func fetchRequest() -> NSFetchRequest<HistoryBudgetHolderMO> {
return NSFetchRequest<HistoryBudgetHolderMO>(entityName: "HistoryBudgetHolder");
}
@NSManaged public var budgets: NSSet?
}
extension HistoryBudgetHolderMO {
@objc(addBudgetsObject:)
@NSManaged public func addToBudgets(_ value: NewBudgetCreateMO)
@objc(removeBudgetsObject:)
@NSManaged public func removeFromBudgets(_ value: NewBudgetCreateMO)
@objc(addBudgets:)
@NSManaged public func addToBudgets(_ values: NSSet)
@objc(removeBudgets:)
@NSManaged public func removeFromBudgets(_ values: NSSet)
}
所以我假设我可以只使用 "addToBudgets" 添加一组数据,它似乎确实有效,但只有一个实例。
我在哪里添加
所以我在 HistoryBudgetHolderMO 上执行了一个获取请求,以查看数据库中是否有任何内容。如果没有,那么我从我的 App Delegate 创建一个新的(请注意:我已经在上面的方法中完成了 App Delegate 转换等,然后将 App Delegate 和 Context 传递给了这个方法)
private func SaveAndDeleteCurrentBudget(context : NSManagedObjectContext, appDele : AppDelegate){
let fetchHistory : NSFetchRequest<HistoryBudgetHolderMO> = HistoryBudgetHolderMO.fetchRequest()
//Saves the budget to the history budget. If we don't have oen we created one and add it to that
do{
let historyBudgets : [HistoryBudgetHolderMO] = try context.fetch(fetchHistory)
if historyBudgets.count <= 0{
let newHistoryBudget : HistoryBudgetHolderMO = HistoryBudgetHolderMO(context: context)
newHistoryBudget.addToBudgets(budgetData.first!)
print("entered new historyBudget")
}else{
historyBudgets.first!.addToBudgets(budgetData.first!)
}
appDele.saveContext()
}catch{
print("Error when looking for history fetch result")
}
//Deletes all budget data and budget entries that are currently used
for object in budgetData{
context.delete(object)
}
let fetchAllDataEntries = NSFetchRequest<NSFetchRequestResult>(entityName: "BudgetEntry")
let deleteReq = NSBatchDeleteRequest(fetchRequest: fetchAllDataEntries)
do{
try context.execute(deleteReq)
}catch{
print("Error when deleting budget entries")
}
appDele.saveContext()
}
- 我执行获取请求并检查是否存在历史实体。如果没有,那么我创建一个新的,添加预算条目,然后保存上下文。
- 如果不是,那么我会获取历史记录持有者的第一个实例(因为它只是一个容器,所以应该只有一个),然后添加预算条目然后保存。
哪里变坏了
所以我第一次这样做时它处于状态 2,我得到一个 Optional(1) 的值,这意味着它已经存储了一个历史条目。然而,在此之后的任何更多添加都继续说它是可选的(1)。我已经尝试查找无数解决方案,尝试弄乱扩展等。我认为这将是一个简单的 Get/Set 操作,但它就是行不通。
如有任何帮助,我们将不胜感激。
感谢您花时间阅读本文。
任何感兴趣的人的解决方案
正如我之前提到的,我仍在学习核心数据,我很感谢 KaraBenNensi 的评论让我思考。
对,所以不需要 "holder" 类型的对象。相反,我所做的是我使用了我预算的最后一个索引。所以每次我创建新预算时,我只是将它们全部保存在数组中。所以与其说:
budgetData.first!.attributeName
我现在用
budgetData.last!.attributeName.
这意味着我的数据库会增长,但它会随着历史记录的持有者而增长。现在,当我想显示历史记录时,我只需从 budgetData 核心数据模型中获取所有结果。当我想显示我的实际预算时,我只使用 .last 以便获得最近创建的预算。
我希望这对某人有所帮助,我很高兴我能弄明白。如果以后有人需要帮助,请回复此消息,我会尽力提供帮助(但我不是专家!)
您的解决方案现在看来不错。我还建议摆脱 HistoryBudgetHolderMO class。我可以建议向 NewBudget class 添加另一个 field/property:一个 creationDate(日期类型)。这样你就可以随时获取最新的(例如获取所有这些并按创建日期排序)。您还可以添加 active/historic 布尔值 属性 以将预算标记为 active/inactive。另一个建议是尽量避免强制展开。而不是写
budgetData.first!.attributeName
尝试使用 'if let' 结构
if let budget = budgetData.first {
budget.attributeName
}
这是我第一次在 swift 中使用核心数据。我真的很喜欢它,但确保我的 Appdelegate 保存等也是一个挑战
问题
基本上我正在创建一个预算应用程序。预算结束后,我需要获取当前预算并将其存储到历史实体中。现在我有 2 个不同的实体在这里工作:
NewBudgetCreateMO 和 HistoryBudgetHolderMO。应该发生的是 HistoryBudgetHolder 应该将预算 (newBudgetCreateMO) 添加到它的一对多关系中。这是我的图表及其关系的图像。
现在,如果我设置正确,我应该允许在我的历史记录中添加任意数量的 NewBudgetCreateMO?下面的代码是为我的历史实体生成的代码,它显示它包含一个 NSSet
extension HistoryBudgetHolderMO {
@nonobjc public class func fetchRequest() -> NSFetchRequest<HistoryBudgetHolderMO> {
return NSFetchRequest<HistoryBudgetHolderMO>(entityName: "HistoryBudgetHolder");
}
@NSManaged public var budgets: NSSet?
}
extension HistoryBudgetHolderMO {
@objc(addBudgetsObject:)
@NSManaged public func addToBudgets(_ value: NewBudgetCreateMO)
@objc(removeBudgetsObject:)
@NSManaged public func removeFromBudgets(_ value: NewBudgetCreateMO)
@objc(addBudgets:)
@NSManaged public func addToBudgets(_ values: NSSet)
@objc(removeBudgets:)
@NSManaged public func removeFromBudgets(_ values: NSSet)
}
所以我假设我可以只使用 "addToBudgets" 添加一组数据,它似乎确实有效,但只有一个实例。
我在哪里添加
所以我在 HistoryBudgetHolderMO 上执行了一个获取请求,以查看数据库中是否有任何内容。如果没有,那么我从我的 App Delegate 创建一个新的(请注意:我已经在上面的方法中完成了 App Delegate 转换等,然后将 App Delegate 和 Context 传递给了这个方法)
private func SaveAndDeleteCurrentBudget(context : NSManagedObjectContext, appDele : AppDelegate){
let fetchHistory : NSFetchRequest<HistoryBudgetHolderMO> = HistoryBudgetHolderMO.fetchRequest()
//Saves the budget to the history budget. If we don't have oen we created one and add it to that
do{
let historyBudgets : [HistoryBudgetHolderMO] = try context.fetch(fetchHistory)
if historyBudgets.count <= 0{
let newHistoryBudget : HistoryBudgetHolderMO = HistoryBudgetHolderMO(context: context)
newHistoryBudget.addToBudgets(budgetData.first!)
print("entered new historyBudget")
}else{
historyBudgets.first!.addToBudgets(budgetData.first!)
}
appDele.saveContext()
}catch{
print("Error when looking for history fetch result")
}
//Deletes all budget data and budget entries that are currently used
for object in budgetData{
context.delete(object)
}
let fetchAllDataEntries = NSFetchRequest<NSFetchRequestResult>(entityName: "BudgetEntry")
let deleteReq = NSBatchDeleteRequest(fetchRequest: fetchAllDataEntries)
do{
try context.execute(deleteReq)
}catch{
print("Error when deleting budget entries")
}
appDele.saveContext()
}
- 我执行获取请求并检查是否存在历史实体。如果没有,那么我创建一个新的,添加预算条目,然后保存上下文。
- 如果不是,那么我会获取历史记录持有者的第一个实例(因为它只是一个容器,所以应该只有一个),然后添加预算条目然后保存。
哪里变坏了
所以我第一次这样做时它处于状态 2,我得到一个 Optional(1) 的值,这意味着它已经存储了一个历史条目。然而,在此之后的任何更多添加都继续说它是可选的(1)。我已经尝试查找无数解决方案,尝试弄乱扩展等。我认为这将是一个简单的 Get/Set 操作,但它就是行不通。
如有任何帮助,我们将不胜感激。
感谢您花时间阅读本文。
任何感兴趣的人的解决方案
正如我之前提到的,我仍在学习核心数据,我很感谢 KaraBenNensi 的评论让我思考。
对,所以不需要 "holder" 类型的对象。相反,我所做的是我使用了我预算的最后一个索引。所以每次我创建新预算时,我只是将它们全部保存在数组中。所以与其说:
budgetData.first!.attributeName
我现在用
budgetData.last!.attributeName.
这意味着我的数据库会增长,但它会随着历史记录的持有者而增长。现在,当我想显示历史记录时,我只需从 budgetData 核心数据模型中获取所有结果。当我想显示我的实际预算时,我只使用 .last 以便获得最近创建的预算。
我希望这对某人有所帮助,我很高兴我能弄明白。如果以后有人需要帮助,请回复此消息,我会尽力提供帮助(但我不是专家!)
您的解决方案现在看来不错。我还建议摆脱 HistoryBudgetHolderMO class。我可以建议向 NewBudget class 添加另一个 field/property:一个 creationDate(日期类型)。这样你就可以随时获取最新的(例如获取所有这些并按创建日期排序)。您还可以添加 active/historic 布尔值 属性 以将预算标记为 active/inactive。另一个建议是尽量避免强制展开。而不是写
budgetData.first!.attributeName
尝试使用 'if let' 结构
if let budget = budgetData.first {
budget.attributeName
}