Swift 如何加上「;一对一;“的一部分;“一对多”;获取结果

Swift 如何加上「;一对一;“的一部分;“一对多”;获取结果,swift,core-data,one-to-many,nsfetchrequest,Swift,Core Data,One To Many,Nsfetchrequest,我希望能够将玩家的数据添加到许多关系的“一对一”部分。提取为我做了一些聚合,但我想知道它属于什么player 我有一个CoreData模型,如下所示: func statsPerPlayer(player: Players, managedContext: NSManagedObjectContext) -> [String: Int] { var resultsDic = [String: Int]() let fetchRequest = NSFetchReque

我希望能够将玩家的数据添加到许多关系的“一对一”部分。提取为我做了一些聚合,但我想知道它属于什么
player

我有一个CoreData模型,如下所示:

func statsPerPlayer(player: Players, managedContext: NSManagedObjectContext)  -> [String: Int] {

    var resultsDic = [String: Int]()

    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Shifts")
    let predicate               = NSPredicate(format: "playersRelationship = %@", player)
    fetchRequest.predicate      = predicate

    let nsExpressionForKeyPath  = NSExpression(forKeyPath: "timeOnIce")

    let nsExpressionForFunctionMin = NSExpression(forFunction: "min:", arguments: [nsExpressionForKeyPath])
    let nsExpressionDescriptionMin = NSExpressionDescription()
    nsExpressionDescriptionMin.expression = nsExpressionForFunctionMin
    nsExpressionDescriptionMin.name = "minShift"
    nsExpressionDescriptionMin.expressionResultType = .integer16AttributeType

    let nsExpressionForFunctionMax = NSExpression(forFunction: "max:", arguments: [nsExpressionForKeyPath])
    let nsExpressionDescriptionMax = NSExpressionDescription()
    nsExpressionDescriptionMax.expression = nsExpressionForFunctionMax
    nsExpressionDescriptionMax.name = "maxShift"
    nsExpressionDescriptionMax.expressionResultType = .integer16AttributeType

    let nsExpressionForFunctionSum = NSExpression(forFunction: "sum:", arguments: [nsExpressionForKeyPath])
    let nsExpressionDescriptionSum = NSExpressionDescription()
    nsExpressionDescriptionSum.expression = nsExpressionForFunctionSum
    nsExpressionDescriptionSum.name = "sumShift"
    nsExpressionDescriptionSum.expressionResultType = .integer16AttributeType

    let nsExpressionForFunctionAvg = NSExpression(forFunction: "average:", arguments: [nsExpressionForKeyPath])
    let nsExpressionDescriptionAvg = NSExpressionDescription()
    nsExpressionDescriptionAvg.expression = nsExpressionForFunctionAvg
    nsExpressionDescriptionAvg.name = "avgShift"
    nsExpressionDescriptionAvg.expressionResultType = .integer16AttributeType

    let nsExpressionForFunctionCount = NSExpression(forFunction: "count:", arguments: [nsExpressionForKeyPath])
    let nsExpressionDescriptionCount = NSExpressionDescription()
    nsExpressionDescriptionCount.expression = nsExpressionForFunctionCount
    nsExpressionDescriptionCount.name = "countShift"
    nsExpressionDescriptionCount.expressionResultType = .integer16AttributeType

    fetchRequest.propertiesToFetch   = [nsExpressionDescriptionMin, nsExpressionDescriptionMax, nsExpressionDescriptionSum, nsExpressionDescriptionAvg, nsExpressionDescriptionCount]

    fetchRequest.resultType = .dictionaryResultType

    do {

        let fetchArray = try managedContext.fetch(fetchRequest)
        print(fetchArray)
        resultsDic = fetchArray.first as! [String : Int]

    } catch let error as NSError {

        print("\(self) -> \(#function): Could not fetch. \(error), \(error.userInfo)")
    }

    return resultsDic

}  //statsPerPlayer

我有一个如下所示的获取请求:

func statsPerPlayer(player: Players, managedContext: NSManagedObjectContext)  -> [String: Int] {

    var resultsDic = [String: Int]()

    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Shifts")
    let predicate               = NSPredicate(format: "playersRelationship = %@", player)
    fetchRequest.predicate      = predicate

    let nsExpressionForKeyPath  = NSExpression(forKeyPath: "timeOnIce")

    let nsExpressionForFunctionMin = NSExpression(forFunction: "min:", arguments: [nsExpressionForKeyPath])
    let nsExpressionDescriptionMin = NSExpressionDescription()
    nsExpressionDescriptionMin.expression = nsExpressionForFunctionMin
    nsExpressionDescriptionMin.name = "minShift"
    nsExpressionDescriptionMin.expressionResultType = .integer16AttributeType

    let nsExpressionForFunctionMax = NSExpression(forFunction: "max:", arguments: [nsExpressionForKeyPath])
    let nsExpressionDescriptionMax = NSExpressionDescription()
    nsExpressionDescriptionMax.expression = nsExpressionForFunctionMax
    nsExpressionDescriptionMax.name = "maxShift"
    nsExpressionDescriptionMax.expressionResultType = .integer16AttributeType

    let nsExpressionForFunctionSum = NSExpression(forFunction: "sum:", arguments: [nsExpressionForKeyPath])
    let nsExpressionDescriptionSum = NSExpressionDescription()
    nsExpressionDescriptionSum.expression = nsExpressionForFunctionSum
    nsExpressionDescriptionSum.name = "sumShift"
    nsExpressionDescriptionSum.expressionResultType = .integer16AttributeType

    let nsExpressionForFunctionAvg = NSExpression(forFunction: "average:", arguments: [nsExpressionForKeyPath])
    let nsExpressionDescriptionAvg = NSExpressionDescription()
    nsExpressionDescriptionAvg.expression = nsExpressionForFunctionAvg
    nsExpressionDescriptionAvg.name = "avgShift"
    nsExpressionDescriptionAvg.expressionResultType = .integer16AttributeType

    let nsExpressionForFunctionCount = NSExpression(forFunction: "count:", arguments: [nsExpressionForKeyPath])
    let nsExpressionDescriptionCount = NSExpressionDescription()
    nsExpressionDescriptionCount.expression = nsExpressionForFunctionCount
    nsExpressionDescriptionCount.name = "countShift"
    nsExpressionDescriptionCount.expressionResultType = .integer16AttributeType

    fetchRequest.propertiesToFetch   = [nsExpressionDescriptionMin, nsExpressionDescriptionMax, nsExpressionDescriptionSum, nsExpressionDescriptionAvg, nsExpressionDescriptionCount]

    fetchRequest.resultType = .dictionaryResultType

    do {

        let fetchArray = try managedContext.fetch(fetchRequest)
        print(fetchArray)
        resultsDic = fetchArray.first as! [String : Int]

    } catch let error as NSError {

        print("\(self) -> \(#function): Could not fetch. \(error), \(error.userInfo)")
    }

    return resultsDic

}  //statsPerPlayer
但是,我想包括此数据所针对的
播放器
。如何在结果中添加
一对多
关系的
“到一”
部分


谢谢

在上面的代码中,只需将相关关系名称添加到要获取的属性:

fetchRequest.propertiesToFetch   = ["playersRelationship", nsExpressionDescriptionMin, nsExpressionDescriptionMax, nsExpressionDescriptionSum, nsExpressionDescriptionAvg, nsExpressionDescriptionCount]
然后,返回的词典将包括键“playersRelationship”,其值设置为相应
Players
对象的
NSManagedObjectID
。然后,您可以使用上下文的
对象(with:)
方法访问
Players
对象本身

更新

所以经过一些测试,结果是:

a) 如果将关系包含在propertiesToFetch中,则CoreData会对
count
aggregate函数产生混淆。这将导致
无效的密钥路径(请求对仅toOne密钥路径进行聚合操作)
错误

b) 如果在propertiesToFetch中包含关系,则会混淆所有其他聚合函数的CoreData。(它计算每个对象的聚合,而不仅仅是匹配谓词的对象。)

这两个问题的解决方案都是按属性将关系添加为GROUP BY。CoreData随后正确计算聚合,并正确识别
count
为有效操作。因此,添加以下行:

fetchRequest.propertiesToGroupBy   = ["playersRelationship"]

如果您只是将“playersRelationship”添加到属性数组estofetch会发生什么?如果我添加
player.playersShiftRelationship如果我添加
shifts.playersRelationship,我会将
无法识别的选择器发送到实例
我收到了相同的错误。您正在获取移位,因此需要在移位实体上指定关系的名称,即“PlayerRelationship”。我想我会按照您的建议执行:
让实体=NSEntityDescription.entity(forEntityName:“移位”,in:managedContext)让移位=移位(entity:entity!,insertInto:managedContext)
我得到了以下错误:
[error]错误:异常处理请求:,无效的keypath(请求在仅toOne的keypath上进行聚合操作):用户信息为(null)的timeOnIce
@PaulS。我不明白为什么会这样;您能用当前代码和错误编辑您的原始帖子吗(s)。当前代码与发布的代码完全相同,错误也相同。@pbasdf做得很好,谢谢。这可能是我唯一没有尝试的组合。你知道一种快速的方法,可以在我所有的
播放器
中运行上述内容,而不需要另一个
播放器
获取和for in循环吗?只要删除谓词-返回的数组将每个玩家有一本字典。