0

请原谅代码墙,但我需要设置舞台......

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); 了 Oddly,最终插入了工作人员、监护人和教师,但两个交叉表都没有任何数据......

--更新---我刚试过 conn.InsertOrReplaceWithChildren(student.Teachers); conn.InsertOrReplaceWithChildren(student.Guardians); conn.InsertOrReplaceWithChildren(student); 而且效果很好......问题是为什么?为什么多对多似乎依赖于操作顺序?

4

1 回答 1

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以及StaffStudent只读属性的关系,因此 SQLite-Net 扩展在将对象保存到数据库时将忽略此关系。

然后,您可以使用recursive任何 SQLite-Net Extensions 方法的参数来true

conn.InsertOrReplaceWithChildren(student, recursive: true);

SQLite-Net Extensions 将正确处理反向关系和关系循环。

于 2015-04-03T14:42:54.007 回答