首页 文章

如何通过关系设置实体属性?

提问于
浏览
0

我有以下实体和关系

enter image description here

如果这有意义的话,我希望能够将练习设置为其常规名称关系的结果为零?以便以后可以在形成例程实体时将其设置为例程名称 .

我的问题是,你如何设置这种属性?我正在尝试以下代码但它会导致致命的崩溃:

userExercise.usersroutine?.name = nil

我的逻辑是我参加练习并遵循与name属性的关系并将其设置为nil?

感谢您对我的逻辑进行任何更正和澄清

EDIT: Added my existing exercise and routine save functions

func createExercise() {
    guard let managedObjectContext = managedObjectContext else { return }
   if let userExercise = userExercise {
        userExercise.name = userExerciseName.text
        userExercise.sets = Int64(userSetsCount)
        userExercise.reps = Int64(userRepsCount)
        userExercise.weight = Double(self.userExerciseWeight.text!)!
        userExercise.id = UUID().uuidString
        userExercise.routine = nil
    }
    do {
        try managedObjectContext.save()
    } catch {
        fatalError("Failure to save context: \(error)")
    }
}

常规创作:

func createRoutine() {

    guard let managedObjectContext = managedObjectContext else { return }
    let userRoutine = UserRoutine(context: managedObjectContext)
    userRoutine.name = workoutNameTextfield.text

    do {
        try managedObjectContext.save()
    } catch {
        fatalError("Failure to save context: \(error)")
    }
}

当前获取请求:

fileprivate lazy var fetchedResultsController: NSFetchedResultsController<UserExercise> = {

    let fetchRequest: NSFetchRequest<UserExercise> = UserExercise.fetchRequest()
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "id", ascending: true)]
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)
    fetchedResultsController.delegate = self
    return fetchedResultsController

2 回答

  • 1

    请检查下面的实现我已经创建了一些练习和例程 . 同时阅读代码中的注释,这将帮助您弄清楚如何去做 .

    添加新练习的功能

    func createExercise(weight: Int16, respetitions: Int16, name: String, routine: Routine?)->Exercise? {
        let context = getMainContext()
        let exercise = NSEntityDescription.insertNewObject(forEntityName: "Exercise", into: context) as! Exercise
        exercise.setValue(weight, forKey: "weight")
        exercise.setValue(name, forKey: "name")
        exercise.setValue(respetitions, forKey: "rep")
    
        do {
            try context.save()
            return exercise
        }
        catch
        {
            fatalError("unable to Ssavve")
        }
    }
    

    添加新例程的功能

    func createRoutine(name: String, exercises:[Exercise]) {
        let context = getMainContext()
        let routine = NSEntityDescription.insertNewObject(forEntityName: "Routine", into: context) as! Routine
        routine.name = name
    
        //Iterate over Exercise objects & check if routine is nil. 
       //Here if routine is not nil it menas your exercise is already assigned to a routine. 
       //If routine is nil assign routine.addToRelationship(<#T##value: Exercise##Exercise#>) and Also assign routine to the execise.
    
         do {
                try context.save()
            }
            catch
            {
                fatalError("unable to Ssavve")
            }
    
    }
    

    获取主NSManagedObjectContext的函数,我们可以在其上执行核心数据操作

    func getMainContext() -> NSManagedObjectContext {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        return appDelegate.persistentContainer.viewContext
    }
    

    下面,首先,我创建一些与例程没有任何关系的练习

    “创建练习时,例程不存在,之后创建,并设置其名称”

    然后通过传递一些练习来创建例程(You can refer to other answer on how to fetch exercises with routine as nil values

    func initializer() {
            //I'm adding exercises first without routines
            let ex1 = self.createExercise(weight: 10, respetitions: 4, name: "Exercise1", routine: nil)
            let ex2 = self.createExercise(weight: 5, respetitions: 10, name: "Exercise2", routine: nil)
            let ex3 = self.createExercise(weight: 20, respetitions: 2, name: "Exercise3", routine: nil)
            let ex4 = self.createExercise(weight: 5, respetitions: 10, name: "Exercise2", routine: nil)
    
            self.createRoutine(name: "Routine 1", exercises: [ex1!, ex2!]) //You can pass all the exercises or use fetch request to query exercises with routine as nil
            self.createRoutine(name: "Routine 2", exercises: [ex3!, ex4!])
    
            self.createRoutine(name: "Routine 3", exercises: [ex1!, ex2!]) //This routine shall not be adding any execises as they are already added to othe routines
        }
    

    更新create routine函数以查询UserExercise的结果,其中usersroutine为nil

    func createRoutine() {
    
        guard let managedObjectContext = managedObjectContext else { return }
        let userRoutine = UserRoutine(context: managedObjectContext)
        userRoutine.name = workoutNameTextfield.text
    
    //Getting nil value User Exercises        
        let request: NSFetchRequest<UserExercise> = UserExercise.fetchRequest()
                    request.predicate = NSPredicate(format: "usersroutine == nil")
                    do {
                        let appDelegate = UIApplication.shared.delegate as! AppDelegate
                        let context = appDelegate.persistentContainer.viewContext
                        let queryResults = try context.fetch(request)
    
                        //I like to check the size of the returned results!
                        print ("num of results = \(queryResults.count)")
    
                        //You need to convert to NSManagedObject to use 'for' loops
                        for exercise in queryResults as [NSManagedObject] {
                            //get the Key Value pairs (although there may be a better way to do that...
                            print("Exercise NAME: \(exercise.value(forKey: "name"))")
                        }
                    } catch {
                        print("Error with request: \(error)")
                    }
    
    
            do {
                try managedObjectContext.save()
            } catch {
                fatalError("Failure to save context: \(error)")
            }
        }
    
  • 0

    您似乎根本不需要使用 name 属性 . 此属性应用于存储 UserRoutine 的实际名称,而不是基于任何关系 .

    Core Data中的实体之间的关系不依赖于实体的特定属性,而是依赖于实体本身 .

    “我希望例程构建器查看练习并导入所有与nil关系的练习”

    所以...

    创建一个获取请求以获取 UserExercise 的所有没有相关 UserRoutine 的实体(即 userroutine 为零) .

    let orphanedExerciseFetchRequest = NSFetchRequest(entityName: "UserExercises")
    orphanedExerciseFetchRequest.predicate = NSPredicate(format: "userroutine == nil)
    

    执行此获取请求以获取UserExercises数组(没有相关例程)

    let orphanedExercises = managedObjectContext.executeFetchRequest(orphanedExerciseFetchRequest())
    

    “创建一个带有归因练习的例程”

    将获取的 UserExercise entitit属性 userRoutine 设置为例程(并且不要忘记在管理对象上下文中保存更改) .

    myRoutine.userexercises = orphanedExercises
    

    之后,如果您想要针对特定例程进行练习:

    let fetchRequest = NSFetchRequest(entityName: "UserExercises")
    fetchRequest.predicate = NSPredicate(format: "userroutine == %@", someUserRoutine)
    

相关问题