请原谅代码墙,但我需要设置舞台......
public class Student
{
public string Name { get; set; }
[PrimaryKey]
public string Id { get; set; }
[ManyToMany(typeof(StudentStaff))]
public List<Staff> Teachers { get; set; }
[ManyToMany(typeof(StudentGuardian))]
public List<Guardian> Guardians { get; set; }
}
public class Guardian
{
[PrimaryKey]
public string Id { get; set; }
public string Name{get;set;}
[ManyToMany(typeof(StudentGuardian))]
public List<Student> Students { get; set; }
}
public class Staff
{
[PrimaryKey]
public string Id { get; set; }
public string Name { get; set; }
[ManyToMany(typeof(StudentStaff))]
public List<Student> Students { get; set; }
}
public class StudentStaff
{
[ForeignKey(typeof(Student))]
public string StudentId { get; set; }
[ForeignKey(typeof(Staff))]
public string StaffId { get; set; }
}
public class StudentGuardian
{
[ForeignKey(typeof(Student))]
public string StudentId { get; set; }
[ForeignKey(typeof(Guardian))]
public string GuardianId { get; set; }
}
鉴于这些课程,我应该如何在保持关系的同时将学生,教职员工和监护人员插入数据库?我应该注意服务器返回填充的学生记录,这是我的起点。
我尝试conn.InsertOrReplaceWithChidlren(student);
...插入了学生,学生和学生保护记录,但没有插入实际的工作人员或监护人。
我试过了
conn.InsertOrReplaceWithChildren(student);
conn.InsertOrReplaceWithChildren(student.Teachers);
conn.InsertOrReplaceWithChildren(student.Guardians);
奇怪的是,最后插入了工作人员,监护人和教师,但两个交叉表都没有任何数据......
- 更新---
我刚试过
conn.InsertOrReplaceWithChildren(student.Teachers);
conn.InsertOrReplaceWithChildren(student.Guardians);
conn.InsertOrReplaceWithChildren(student);
它完美地工作......问题是为什么?为什么多对多似乎依赖于操作顺序?
答案 0 :(得分:1)
SQLite-Net Extensions要求为所有对象分配唯一ID以建立关系。使用AutoIncrement
主键,这意味着所有对象都已插入数据库中。
如果没有设置反向关系,顺序也可能会影响,设置反向关系或将这些属性设置为ReadOnly
通常是个好主意,以避免副作用。
话虽这么说,SQLite-Net Extensions提供了帮助完成此任务的实用方法。在这种情况下,您可以使用级联操作来执行单个插入。要启用级联操作,请定义关系属性的CascadeOperations
属性:
public class Student
{
public string Name { get; set; }
[PrimaryKey]
public string Id { get; set; }
[ManyToMany(typeof(StudentStaff), CascadeOperations = CascadeOperation.All)]
public List<Staff> Teachers { get; set; }
[ManyToMany(typeof(StudentGuardian), CascadeOperations = CascadeOperation.All))]
public List<Guardian> Guardians { get; set; }
}
public class Guardian
{
[PrimaryKey]
public string Id { get; set; }
public string Name{get;set;}
[ManyToMany(typeof(StudentGuardian), CascadeOperations = CascadeOperation.All, ReadOnly = true))]
public List<Student> Students { get; set; }
}
public class Staff
{
[PrimaryKey]
public string Id { get; set; }
public string Name { get; set; }
[ManyToMany(typeof(StudentStaff), CascadeOperations = CascadeOperation.All, ReadOnly = true))]
public List<Student> Students { get; set; }
}
在此示例中,我还包含ReadOnly
属性以使Guardian
和Staff
与Student
关系成为只读属性,因此SQLite-Net Extensions将忽略此关系将对象保存到数据库中。
然后,您可以使用任何SQLite-Net Extensions方法的recursive
参数true
:
conn.InsertOrReplaceWithChildren(student, recursive: true);
SQLite-Net Extensions将正确处理反向关系和关系循环。