如何通过关系设置实体属性?
How to set an entities attribute via relationship?
我有以下实体和关系
我希望能够将练习设置为其例程名称关系的结果为零,这是否有意义?以便稍后在形成例程实体时将其设置为例程名称。
我的问题是,你是如何设置这种属性的?我正在尝试以下代码,但它会导致致命崩溃:
userExercise.usersroutine?.name = nil
我的逻辑是我进行练习并遵循与名称 属性 的关系并将其设置为零?
感谢您对我的逻辑的任何更正和澄清
编辑:添加了我现有的练习和例程保存功能
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
请检查下面的实现我已经创建了一些练习和例程。另请阅读代码中的注释,这将帮助您弄清楚如何去做。
添加新练习的功能
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
}
下面,首先我创建一些与套路无关的练习
"The routine doesnt exist when the exercises are created, it is created afterward and its name is set"
然后通过一些练习来创建例程()
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
}
正在更新创建例程函数以查询用户例程为 nil 的 UserExercise 结果
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)")
}
}
您似乎根本不需要使用 name
属性。此属性应该用于存储 UserRoutine
的实际名称,而不是基于任何关系。
Core Data 中实体之间的关系不依赖于实体的特定属性,而是实体之间的关系。
"I want the routine builder to look at the exercises and import all the exercises with nil in the relationship into it"
所以...
创建获取请求以获取 UserExercise
中没有相关 UserRoutine
的所有实体(即 userroutine
为 nil)。
let orphanedExerciseFetchRequest = NSFetchRequest(entityName: "UserExercises")
orphanedExerciseFetchRequest.predicate = NSPredicate(format: "userroutine == nil)
执行此获取请求以获取一组 UserExercises(没有相关例程)
let orphanedExercises = managedObjectContext.executeFetchRequest(orphanedExerciseFetchRequest())
"creating a routine with attributed exercises"
将获取的 UserExercise
实体的 属性 userRoutine
设置为您的例程(并且不要忘记将更改保存在您的托管对象上下文中)。
myRoutine.userexercises = orphanedExercises
稍后,如果您想获取特定例程的练习:
let fetchRequest = NSFetchRequest(entityName: "UserExercises")
fetchRequest.predicate = NSPredicate(format: "userroutine == %@", someUserRoutine)
我有以下实体和关系
我希望能够将练习设置为其例程名称关系的结果为零,这是否有意义?以便稍后在形成例程实体时将其设置为例程名称。
我的问题是,你是如何设置这种属性的?我正在尝试以下代码,但它会导致致命崩溃:
userExercise.usersroutine?.name = nil
我的逻辑是我进行练习并遵循与名称 属性 的关系并将其设置为零?
感谢您对我的逻辑的任何更正和澄清
编辑:添加了我现有的练习和例程保存功能
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
请检查下面的实现我已经创建了一些练习和例程。另请阅读代码中的注释,这将帮助您弄清楚如何去做。
添加新练习的功能
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
}
下面,首先我创建一些与套路无关的练习
"The routine doesnt exist when the exercises are created, it is created afterward and its name is set"
然后通过一些练习来创建例程(
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
}
正在更新创建例程函数以查询用户例程为 nil 的 UserExercise 结果
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)")
}
}
您似乎根本不需要使用 name
属性。此属性应该用于存储 UserRoutine
的实际名称,而不是基于任何关系。
Core Data 中实体之间的关系不依赖于实体的特定属性,而是实体之间的关系。
"I want the routine builder to look at the exercises and import all the exercises with nil in the relationship into it"
所以...
创建获取请求以获取 UserExercise
中没有相关 UserRoutine
的所有实体(即 userroutine
为 nil)。
let orphanedExerciseFetchRequest = NSFetchRequest(entityName: "UserExercises")
orphanedExerciseFetchRequest.predicate = NSPredicate(format: "userroutine == nil)
执行此获取请求以获取一组 UserExercises(没有相关例程)
let orphanedExercises = managedObjectContext.executeFetchRequest(orphanedExerciseFetchRequest())
"creating a routine with attributed exercises"
将获取的 UserExercise
实体的 属性 userRoutine
设置为您的例程(并且不要忘记将更改保存在您的托管对象上下文中)。
myRoutine.userexercises = orphanedExercises
稍后,如果您想获取特定例程的练习:
let fetchRequest = NSFetchRequest(entityName: "UserExercises")
fetchRequest.predicate = NSPredicate(format: "userroutine == %@", someUserRoutine)