核心数据一对多关系未保存 correctly/as 预期
Core Data One to Many Relationship not saving correctly/as expected
我有一个包含以下 NSManagedObjects 的核心数据项目:
************************ FSDJump NSManaged 对象
extension FSDJump {
@nonobjc public class func fetchRequest() -> NSFetchRequest<FSDJump> {
return NSFetchRequest<FSDJump>(entityName: "FSDJump")
}
@NSManaged public var starSystem: String
@NSManaged public var starPos: NSArray
@NSManaged public var bodyName: String
@NSManaged public var jumpDist: Float
@NSManaged public var fuelUsed: Float
@NSManaged public var fuelLevel: Float
@NSManaged public var boostUsed: Bool
@NSManaged public var systemFaction: String
@NSManaged public var systemAllegiance: String
@NSManaged public var systemEconomy: String
@NSManaged public var systemGoverment: String
@NSManaged public var systemSecurity: String
@NSManaged public var powers: NSArray
@NSManaged public var powerplayState: String
@NSManaged public var timeStamp: String
@NSManaged public var factionState: String
@NSManaged public var factions: NSSet
}
// MARK:为派系生成访问器
扩展 FSDJump {
@objc(addFactionsObject:)
@NSManaged public func addToFactions(_ value: Factions)
@objc(removeFactionsObject:)
@NSManaged public func removeFromFactions(_ value: Factions)
@objc(addFactions:)
@NSManaged public func addToFactions(_ values: NSSet)
@objc(removeFactions:)
@NSManaged public func removeFromFactions(_ values: NSSet)
}
************************ 派系 NSManaged 对象
extension Factions {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Factions> {
return NSFetchRequest<Factions>(entityName: "Factions")
}
@NSManaged public var name: String
@NSManaged public var allegiance: String
@NSManaged public var factionState: String
@NSManaged public var government: String
@NSManaged public var influence: Float
@NSManaged public var fsdJump: FSDJump
}
在 FSDJump 和 Factions 之间定义一对多关系(即一个 FSDJump 可能有多个派系(反向关系定义为 'fsdJump')。
我使用以下代码在 'if else' 语句中保存多个 Factions(它们存在的地方)保存每个 fsdJumpEvent。
if fsdJumpEvent["Factions"].exists() {
// save all of the Faction array objects in the variable arrayOfFactions
let arrayOfFactions = fsdJumpEvent["Factions"]
// create a newFaction managedObject to save the faction details to
let newFaction = (Factions(context: contextTCCEDJ))
for faction in arrayOfFactions {
// the following is strictly not necesary but it makes the code easier to read
// first allocate the values from faction to a local variable then allocate that variable to the newFaction managedObject
// Note faction is a tuple (string, JSON) so the construct 'faction.1' accesses the second value in the tuple
// 'faction.0' would access the first value in the tuple which is the array index "0", "1", "2", etc
let newFactionName = faction.1["Name"].string!
let newFactionState = faction.1["FactionState"].string!
let newFactionGovernment = faction.1["Government"].string!
let newFactionAllegiance = faction.1["Allegiance"].string!
let newFactionInfluence = faction.1["Influence"].float!
newFaction.name = newFactionName
newFaction.allegiance = newFactionAllegiance
newFaction.government = newFactionGovernment
newFaction.influence = newFactionInfluence
newFaction.factionState = newFactionState
// Add the new object to the context allowing it to be saved.
fsdJump.addToFactions(newFaction)
print("Faction added \(newFaction)")
}
}
代码似乎有效。它构建、运行并且 print("Faction added \(newFaction)")
语句按预期在每个 FSDJump 存在时打印多个派系,并根据我正在使用的源数据文件 (JSON).
我可以获取结果并将它们显示在 NSTableView 中。我可以毫无问题地为 FSDJump 托管对象加载数据并将其显示在 NSTableView 中。
获取代码为:
// Function returns all of the Factions associated with the timeStamp related entry in FSDJumps using the fsdJump relationship
func eventFactionsFetchSavedDataFromPersistenStore (contextTCCEDJ: NSManagedObjectContext, timeStamp: String) -> [Factions] {
var result = Array<Factions>()
let localFetchRequest = Factions.fetchRequest() as NSFetchRequest
localFetchRequest.predicate = NSPredicate(format:"fsdJump.timeStamp == '\(timeStamp)'")
do {
result = try contextTCCEDJ.fetch(localFetchRequest)
} catch {
print("Error in returning Factions event saved data from the persistent store")
}
print(result.count)
for reSult in result {
print(reSult.fsdJump.timeStamp)
}
return result
}
但是,它似乎只为每个关系保存最后一个 'faction' - 而不是多个派系在 for faction in arrayOfFactions
循环中显示。因为 fetch 语句每次 fetch 只 returns 一个 Faction。即使我删除了谓词语句,它 returns 所有已保存的派系,但每个 fsdJumpEvent 只保存了一个派系,而不是打印语句标识的多个派系。
能想到的我都试过了。我无法找到与此特定问题相关的先前问题。
我是不是用错了'addToFactions'功能?
如有任何帮助,我们将不胜感激。
(是的 - 对于那里的所有 Elite Dangerous 粉丝,我正在编写一个 macOS 应用程序来解析我的日志文件,作为我的 windows 版 Elite Dangerous 的配套应用程序。)
您正在 for faction in arrayOfFactions
循环之外创建一个新的 newFaction
实例。因此,每次循环运行时都会使用单个 newFaction
并为其分配新值(覆盖以前的值),从而导致它以最后一组值结束。因此,您会看到一个具有 'last' 值集的派系。移动线:
Let newFaction = Factions(context: contectTCCEDJ)
for in
循环的内部(开始处)。
编辑:您正在将您的派系添加到一个集合中(根据定义,这需要唯一的实体),因此您目前所做的只是每次都重新添加同一个派系,而不是一个新的派系。对多关系指向一个集合。
我有一个包含以下 NSManagedObjects 的核心数据项目:
************************ FSDJump NSManaged 对象
extension FSDJump {
@nonobjc public class func fetchRequest() -> NSFetchRequest<FSDJump> {
return NSFetchRequest<FSDJump>(entityName: "FSDJump")
}
@NSManaged public var starSystem: String
@NSManaged public var starPos: NSArray
@NSManaged public var bodyName: String
@NSManaged public var jumpDist: Float
@NSManaged public var fuelUsed: Float
@NSManaged public var fuelLevel: Float
@NSManaged public var boostUsed: Bool
@NSManaged public var systemFaction: String
@NSManaged public var systemAllegiance: String
@NSManaged public var systemEconomy: String
@NSManaged public var systemGoverment: String
@NSManaged public var systemSecurity: String
@NSManaged public var powers: NSArray
@NSManaged public var powerplayState: String
@NSManaged public var timeStamp: String
@NSManaged public var factionState: String
@NSManaged public var factions: NSSet
}
// MARK:为派系生成访问器 扩展 FSDJump {
@objc(addFactionsObject:)
@NSManaged public func addToFactions(_ value: Factions)
@objc(removeFactionsObject:)
@NSManaged public func removeFromFactions(_ value: Factions)
@objc(addFactions:)
@NSManaged public func addToFactions(_ values: NSSet)
@objc(removeFactions:)
@NSManaged public func removeFromFactions(_ values: NSSet)
}
************************ 派系 NSManaged 对象
extension Factions {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Factions> {
return NSFetchRequest<Factions>(entityName: "Factions")
}
@NSManaged public var name: String
@NSManaged public var allegiance: String
@NSManaged public var factionState: String
@NSManaged public var government: String
@NSManaged public var influence: Float
@NSManaged public var fsdJump: FSDJump
}
在 FSDJump 和 Factions 之间定义一对多关系(即一个 FSDJump 可能有多个派系(反向关系定义为 'fsdJump')。
我使用以下代码在 'if else' 语句中保存多个 Factions(它们存在的地方)保存每个 fsdJumpEvent。
if fsdJumpEvent["Factions"].exists() {
// save all of the Faction array objects in the variable arrayOfFactions
let arrayOfFactions = fsdJumpEvent["Factions"]
// create a newFaction managedObject to save the faction details to
let newFaction = (Factions(context: contextTCCEDJ))
for faction in arrayOfFactions {
// the following is strictly not necesary but it makes the code easier to read
// first allocate the values from faction to a local variable then allocate that variable to the newFaction managedObject
// Note faction is a tuple (string, JSON) so the construct 'faction.1' accesses the second value in the tuple
// 'faction.0' would access the first value in the tuple which is the array index "0", "1", "2", etc
let newFactionName = faction.1["Name"].string!
let newFactionState = faction.1["FactionState"].string!
let newFactionGovernment = faction.1["Government"].string!
let newFactionAllegiance = faction.1["Allegiance"].string!
let newFactionInfluence = faction.1["Influence"].float!
newFaction.name = newFactionName
newFaction.allegiance = newFactionAllegiance
newFaction.government = newFactionGovernment
newFaction.influence = newFactionInfluence
newFaction.factionState = newFactionState
// Add the new object to the context allowing it to be saved.
fsdJump.addToFactions(newFaction)
print("Faction added \(newFaction)")
}
}
代码似乎有效。它构建、运行并且 print("Faction added \(newFaction)")
语句按预期在每个 FSDJump 存在时打印多个派系,并根据我正在使用的源数据文件 (JSON).
我可以获取结果并将它们显示在 NSTableView 中。我可以毫无问题地为 FSDJump 托管对象加载数据并将其显示在 NSTableView 中。
获取代码为:
// Function returns all of the Factions associated with the timeStamp related entry in FSDJumps using the fsdJump relationship
func eventFactionsFetchSavedDataFromPersistenStore (contextTCCEDJ: NSManagedObjectContext, timeStamp: String) -> [Factions] {
var result = Array<Factions>()
let localFetchRequest = Factions.fetchRequest() as NSFetchRequest
localFetchRequest.predicate = NSPredicate(format:"fsdJump.timeStamp == '\(timeStamp)'")
do {
result = try contextTCCEDJ.fetch(localFetchRequest)
} catch {
print("Error in returning Factions event saved data from the persistent store")
}
print(result.count)
for reSult in result {
print(reSult.fsdJump.timeStamp)
}
return result
}
但是,它似乎只为每个关系保存最后一个 'faction' - 而不是多个派系在 for faction in arrayOfFactions
循环中显示。因为 fetch 语句每次 fetch 只 returns 一个 Faction。即使我删除了谓词语句,它 returns 所有已保存的派系,但每个 fsdJumpEvent 只保存了一个派系,而不是打印语句标识的多个派系。
能想到的我都试过了。我无法找到与此特定问题相关的先前问题。
我是不是用错了'addToFactions'功能?
如有任何帮助,我们将不胜感激。
(是的 - 对于那里的所有 Elite Dangerous 粉丝,我正在编写一个 macOS 应用程序来解析我的日志文件,作为我的 windows 版 Elite Dangerous 的配套应用程序。)
您正在 for faction in arrayOfFactions
循环之外创建一个新的 newFaction
实例。因此,每次循环运行时都会使用单个 newFaction
并为其分配新值(覆盖以前的值),从而导致它以最后一组值结束。因此,您会看到一个具有 'last' 值集的派系。移动线:
Let newFaction = Factions(context: contectTCCEDJ)
for in
循环的内部(开始处)。
编辑:您正在将您的派系添加到一个集合中(根据定义,这需要唯一的实体),因此您目前所做的只是每次都重新添加同一个派系,而不是一个新的派系。对多关系指向一个集合。