在Sqlite扩展中没有更新的多对多关系

时间:2015-04-01 20:12:24

标签: sqlite-net-extensions

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

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); 它完美地工作......问题是为什么?为什么多对多似乎依赖于操作顺序?

1 个答案:

答案 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属性以使GuardianStaffStudent关系成为只读属性,因此SQLite-Net Extensions将忽略此关系将对象保存到数据库中。

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

conn.InsertOrReplaceWithChildren(student, recursive: true);

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