Добавление элементов в отношении многие ко многим - PullRequest
0 голосов
/ 27 сентября 2019

Я делаю проект, в котором (с точки зрения школы) вы можете рассчитать среднее значение для каждого учащегося.Вы можете зарегистрировать ученика (первое лицо) на экране и предметы (второе лицо) на другом экране.У ученика есть имя, адрес электронной почты, оценка и среднее значение в качестве атрибутов, а у субъекта есть имяОни связывают многих со многими.

Я пытаюсь создать копию списка предметов для каждого учащегося, затем для каждого учащегося я могу зарегистрировать оценку по каждому предмету.Например:

Концепция модели

Модель:! https://imgur.com/gmXyR5j

Я создал один предмет, поскольку он используется более чем в одномlocation:

import Foundation
import CoreData

class SubjectsManager {
    static let shared = SubjectsManager()
    var subjects: [Subject] = []

    func loadSubject(with context: NSManagedObjectContext) {
        let fetchRequest: NSFetchRequest<Subject> = Subject.fetchRequest()
        let sortDescritor = NSSortDescriptor(key: "name", ascending: true)
        fetchRequest.sortDescriptors = [sortDescritor]

        do {
            subjects = try context.fetch(fetchRequest)
        } catch {
            print(error.localizedDescription)
        }
    }

    func deleteSubject(index: Int, context: NSManagedObjectContext) {
        let subject = subjects[index]
        context.delete(subject)

        do {
            try context.save()
            subjects.remove(at: index)
        } catch {
            print(error.localizedDescription)
        }
    }

    private init() {

    }
}

И на экране моего ученика я много чего пробовал, но ничего не получается.Отношение «ко-многим» ученика к предмету называется registeredSubjects Я создал NSSET с именем subjectsManagerSet для получения значений из синглтона, но он не работает.Вот что я пробовал до сих пор:

subjectManagerSet.addingObjects(from: subjectsManager.subjects)

Также пытался создать цикл for subjectManager.subjects для добавления на subjectManagerSet, но он тоже не работает.

Об ошибках,когда я получаю сэмплы из вывода xcode, он продолжает показывать, что subjectManagerSet не получил значения из subjectManager.subject

Сообщение об ошибке:

2019-09-26 20:38:16.983725-0300 MyAverage[1734:62290] Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file /Users/vitorgomes/Desktop/Mentorizacao/MyAverage/MyAverage/Controllers/StudentsViewController.swift, line 119
(lldb) po subjectManagerSet
0 elements

Ожидаемый результат: я хочу получить копиюпредметов для каждого студента, затем я могу добавить оценки для каждого предмета для каждого студента.

1 Ответ

1 голос
/ 27 сентября 2019

Ожидаемый результат заключается в том, что я хочу получить копию предметов для каждого студента, затем я могу добавить оценки по каждому предмету для каждого студента.

Я не рассматриваю вашу проблему какуказано в начале вашего вопроса, но тот, который указан в конце, согласно приведенной выше цитате.

Я бы посоветовал вам пересмотреть структуру вашей модели.

Возможно, что-то подобное?

proposed Core Data object model graph

В этой предлагаемой модели вы можете присвоить объекту сущности Enrolment:

  • a gradedate) через эти свойства атрибута;
  • ученик через свойство отношения один ко многим с сущностью Student;
  • субъект через свойство отношения один ко многим с сущностью Subject.

В следующих примерах я предполагаю, что базовые данные генерируют подклассы NSManagedObject - то есть- в инспекторе модели данных установите значение для Codegen = Определение класса (по умолчанию).

(Лично и в качестве отдельного документа, я предпочитаю вручную писать NSManagedObject подклассы для каждой из моих сущностей и использовать Set вместо NSSet, так как впоследствии я обнаружил, что намного проще поддерживать целостность типов в моем коде. Но я не сделал этого здесь, так как большинство людей, не знакомых с Core Data, будут использовать значение по умолчанию для Codegen, упомянутое выше.)

Вы можете получить доступ к этим значениям следующим образом ...

    let student = Student()

    print("Student name is: \(String(describing: student.name))")

    if let studentEnrolments: NSSet = student.studentEnrolments {

        for item in studentEnrolments {

            if
                let enrolment = item as? Enrolment,
                let subjectName: String = enrolment.subject?.name {

                print("Subject name for this student is: \(subjectName)")
            }
        }
    }

Легко назначить зачисление предмета студенту ...

    let enrolment = Enrolment()
    let subject = Subject()

    enrolment.subject = subject

    student.addToStudentEnrolments(enrolment)

Тогда или сейчас, к зачисленному предмету может быть применена оценка ...

    let grade: String = "A"

    enrolment.grade = grade

Конечно, среднее становится математической функцией, основанной на сумме всех оценок для каждого учащегося, деленной насосчитать.По моему скромному мнению, это лучше сконструировать по мере необходимости, а не сохранять как атрибут с каждым Student объектом.

Обновление

Я обновляю свой ответвключить небольшую теорию базы данных, чтобы объяснить мою предложенную объектную модель.

Согласно Википедии, Нормализация базы данных - это ...

процесс структурирования реляционнойбазы данных в соответствии с рядом так называемых нормальных форм, чтобы уменьшить избыточность данных и улучшить целостность данных.

Что это практически значит для меня?Это означает разбиение моих данных на наиболее дискретные и уникальные части, так что теоретически мне никогда не нужно вводить какие-либо уникальные фрагменты данных более одного раза.

Позвольте мне использовать простой пример таблицы в качестве средстваобъяснения этого, как это может быть указано в электронной таблице (или вашей концепции модели):

Исходные данные

     TABLE 1
     A          B           C
1    STUDENT    SUBJECT     GRADE    
2    Student1   Mathematics 8.8
3    Student1   Physics     7.0
4    Student1   Biology     6.0
5    Student2   Mathematics 5.0
6    Student2   Physics     9.0
7    Student2   Biology     7.0

Нормализованные данные

     TABLE 1                             TABLE 2              TABLE 3
     A          B           C            A     B              A     B
1    STUDENT    SUBJECT     GRADE        ID    STUDENT        ID    SUBJECT
2    1          1           8.8          1     Student1       1     Mathematics
3    1          2           7.0          2     Student2       2     Physics
4    1          3           6.0                               3     Biology
5    2          1           5.0
6    2          2           9.0
7    2          3           7.0

Нормализованные данные используют отношения между тремя таблицами.Он хранит ID (в качестве первичного ключа) каждого STUDENT и каждого SUBJECT вместо фактических слов.Это, очевидно, гораздо более эффективно во многих отношениях, включая, но не ограничиваясь: байты хранимых данных, возможность индексирования, скорость извлечения данных.

Когда вы устанавливаете свойство Relationship вваш граф объектной модели базовых данных, вы делаете то же самое ...

Так что для вашего примера граф объектной модели базовых данных Entity заменяет TABLE.Инфраструктура Core Data автоматически вставляет столбец первичного ключа в базу данных SQLite для нас, когда она создает таблицы, а затем уникальное целое число первичного ключа, когда мы программно добавляем строки (записи, или экземпляры сущности).Хотя у нас как разработчика нет прямого доступа к нему (с использованием Core Data), платформа Core Data позволяет нам строить отношения «один к одному», «один ко многим» и «многие ко многим» между двумя объектами, которые достигают одного и того же результата.

     Enrolment                           Student              Subject
     A          B           C            A     B              A     B
     Rel.       Rel.        Att.         Rel.  Att.           Rel.  Att.
     ∞          ∞                        1                    1
Z_PK Student    Subject     grade        Z_PK  name           Z_PK  name
1    1          1           8.8          1     Student1       1     Mathematics
2    1          2           7.0          2     Student2       2     Physics
3    1          3           6.0                               3     Biology
4    2          1           5.0
5    2          2           9.0
6    2          3           7.0

Att. = объект атрибут ;

Rel. = Сущность Отношения ;

= много сторон от одного ко многим Отношения (<< -);</p>

1 = одна сторона одного ко многим Отношения (->)


Есть вопросы, дайте мне знать?

...