2015-04-01 61 views
0

请原谅的代码在墙上,但我需要设置舞台....多对多关系在SQLite的扩展不更新

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); 奇怪的是,结束了工作人员,监护人和老师插入,但没有交集表中的任何数据...

--update --- 我只是想 conn.InsertOrReplaceWithChildren(student.Teachers); conn.InsertOrReplaceWithChildren(student.Guardians); conn.InsertOrReplaceWithChildren(student); 它的工作完美...问题是为什么?为什么多数人似乎依赖于操作秩序?

回答

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

然后,你可以使用任何的SQLite-Net的扩展方法的recursive参数true

conn.InsertOrReplaceWithChildren(student, recursive: true); 

SQLite的-Net的扩展将处理反向关系,关系正常循环。

+0

嗯,我喜欢只读,我会给其余的一个旋转,让你知道。我不是100%确定你为什么提到自动增量键。我的样品根本就没有。 – user3589700 2015-04-08 00:09:16