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; }
}

これらのクラスが与えられた場合、関係を維持しながら学生、スタッフ、保護者をデータベースに挿入するにはどうすればよいですか? サーバーは入力された Student レコードを返すことに注意してください。これが私の出発点です。

私は試してみconn.InsertOrReplaceWithChidlren(student);ました...学生、学生スタッフ、学生保護者のレコードを挿入しましたが、実際のスタッフや保護者は挿入しませんでした。スタッフ、保護者、教師が挿入されたOddlyを試し conn.InsertOrReplaceWithChildren(student); conn.InsertOrReplaceWithChildren(student.Teachers); conn.InsertOrReplaceWithChildren(student.Guardians); ましたが、どちらの交点テーブルにもデータがありませんでした...

--更新--- 試し conn.InsertOrReplaceWithChildren(student.Teachers); conn.InsertOrReplaceWithChildren(student.Guardians); conn.InsertOrReplaceWithChildren(student); てみたところ、完全に機能しました...問題はなぜですか? 多対多が操作順序に依存しているように見えるのはなぜですか?

4

1 に答える 1

1

SQLite-Net 拡張では、関係を確立するために、すべてのオブジェクトに一意の ID が割り当てられている必要があります。主キーの場合、これAutoIncrementはすべてのオブジェクトがすでにデータベースに挿入されていることを意味します。

逆の関係が設定されていない場合、順序も影響する可能性があります。通常は、逆の関係を設定するか、ReadOnly副作用を避けるためにそれらの属性を設定することをお勧めします。

そうは言っても、SQLite-Net 拡張機能は、このタスクを支援するためのユーティリティ メソッドを提供します。この場合、カスケード操作を利用して単一の挿入を実行できます。カスケード操作を有効にするに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、作成するプロパティと読み取り専用プロパティへの関係も含まれているため、SQLite-Net 拡張機能は、オブジェクトをデータベースに保存するときにこの関係を無視しGuardianますStaffStudent

recursive次に、任意の SQLite-Net 拡張メソッドのパラメーターを使用して、次のことを行うことができますtrue

conn.InsertOrReplaceWithChildren(student, recursive: true);

SQLite-Net 拡張機能は、逆関係と関係ループを正しく処理します。

于 2015-04-03T14:42:54.007 に答える