【问题标题】:Core Data One to Many Relationship not saving correctly/as expected核心数据一对多关系未正确/按预期保存
【发布时间】:2017-05-20 00:34:47
【问题描述】:

我有一个包含以下 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)

}

********************** Factions 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”语句中保存多个 Faction(它们存在的地方),从而保存每个 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 存在时按预期打印多个 Faction,并且根据我正在使用的源数据文件 (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
}

然而,它似乎只保存了每个关系的最后一个“派系”——而不是for faction in arrayOfFactions 循环中显示的多个派系。因为 fetch 语句每次 fetch 只返回一个 Faction。即使我删除了谓词语句,它也会返回所有已保存的派系,但每个 fsdJumpEvent 也只保存了一个派系,而不是 print 语句标识的多个派系。

我已经尝试了我能想到的一切。我无法找到与此特定问题相关的先前问题。

我是否错误地使用了“addToFactions”功能?

如有任何帮助,我们将不胜感激。

(是的 - 对于任何 Elite Dangerous 粉丝,我正在编写一个 macOS 应用程序来解析我的日志文件作为我的 Windows 版本的 Elite Dangerous 的配套应用程序。)

【问题讨论】:

    标签: swift macos core-data one-to-many nsmanagedobject


    【解决方案1】:

    您正在 for faction in arrayOfFactions 循环之外创建一个新的 newFaction 实例。因此,每次循环运行时都会使用单个 newFaction 并为其分配新值(覆盖以前的值),从而导致它以最后一组值结束。因此,您会看到具有“最后”一组值的单个派系。移动线: Let newFaction = Factions(context: contectTCCEDJ) for in 循环的内部(开头)。

    编辑:您正在将您的派系添加到一个集合(根据定义,这需要独特的实体),因此您当前所做的只是每次都重新添加相同的派系,而不是一个新的派系。多对多关系指向一个集合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      相关资源
      最近更新 更多