Реляционная база данных OneToMany

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

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

Более подробно, у вас у многих одинаковые studentId в таблице StudentSpecifications. Если второй набор данных, который будет вставлен, имеет тот же StudentId, это повлияет на первый набор данных и сделает их NULL, но второй набор данных StudentId будет правильным.

StudentId используется как ForeignKey. Я подозреваю, что использую отношение OnetoMany, но не знаю, как с этим справиться?

Student: [
{
  StudentId: "3322449c-cd89-4633-ae3a-4578572eeeee",
  Name: "Joseph Peter",
  Qualification: "1222449c-efds-rfcs-asde-8546242kkkkk",
  StudentSpecifications: [
  {
    Id: "45e63840-0dc3-4296-a83d-97cc462b2dac",
    EnrollDate: "2016-08-05T09:40:21.233",
    GraduationDate: "2017-06-05T09:40:21.233",
   },
   {
    Id: "25fffe40-0dc3-4296-a83d-97cc462b2dac",
    EnrollDate: "2015-07-05T09:40:21.233",
    GraduationDate: "2016-08-05T09:40:21.233",
   },
  }
]

Student.cs

[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<StudentSpecification> StudentSpecifications { get; set; }

public Student(StudentDto dto)
{
    Id = dto.StudentId.ToString();
    Name = dto.Name;
    QualificationId = dto.QualificationId.ToString();
    StudentSpecifications= dto.StudentSpecification.Select(x => new StudentSpecification(x, Id)).ToList();
} 

StudentSpecification.cs

[Table("STUDENT_SPECIFICATIONS")]
public class StudentSpecification
{
    [PrimaryKey]
    public string Id{get;set;}
    [ForeignKey(typeof(Student))]
    public string StudentId { get; set; }
    public DateTime EnrollDate{ get; set; }
    public DateTime GraduationDate{ get; set; }

    public StudentSpecification(StudentDto dto, string studentId)
    {
        Id = Guid.NewGuid().ToString();
        StudentId = studentId;
        EnrollDate= dto.EnrollDate;
        GraduationDate= dto.GraduationDate;
    }

Вставка в таблицу

public bool AddOrUpdate(IEnumerable<T> entities, bool withChildren = false)
{
  var db = _factory.GetConnectionWithLock();
  using (db.Lock())
  {
     db.InsertOrReplaceAllWithChildren(entities, true);
     return true;
   }
}

person casillas    schedule 20.02.2017    source источник
comment
Можете ли вы опубликовать код для Student.cs? Это кажется неполным, и вы не можете аннотировать OneToMany класс.   -  person redent84    schedule 21.02.2017
comment
@redent84, ты прав, это моя ошибка. Я добавил недостающую часть.   -  person casillas    schedule 21.02.2017


Ответы (1)


Вы переопределяете отношение каждый раз, когда сохраняете новый набор данных здесь:

StudentSpecifications= dto.StudentSpecification.Select(x => new StudentSpecification(x, Id)).ToList();

Таким образом, ваш старый StudentSpecifications будет удален из отношения в базе данных, установив для внешнего ключа значение null.

Проблема в том, что вы хотите объединить эти результаты, поэтому вы можете либо загрузить предыдущие элементы из базы данных и объединить их вручную, либо обработать отношения вручную.

Поскольку вы уже назначаете внешний ключ вручную, вы можете просто вставить объекты, используя простые методы SQLite-Net:

db.InsertOrReplace(student);
for (var spec in student.StudentSpecifications) {
    db.InsertOrReplace(spec);
}

Таким образом, ваши старые отношения не будут удалены, а результаты будут объединены в следующий раз, когда вы загрузите их из базы данных.

person redent84    schedule 21.02.2017