稍后检索时保存的项目为空

Saved items are empty when retrieving at a later point

我正在使用 Xamarin 和 C# 制作跨平台应用程序。 SQLite.Net 扩展正在用于本地数据库。用户 table 包含寄存器列表,如下所示:

public class User
{
    [PrimaryKey, AutoIncrement]
    public int UserID { get; set; }
    public string firstName { get; set; }
    public string lastName { get; set; }
    public string title { get; set; }
    public string emailAddress { get; set; }
    public string password { get; set; }      
    //public ObservableCollection<Register> registerList { get; set; }

    [ManyToMany(typeof(RegStudent))]
    public ObservableCollection<Register> Registers { get; set; } 

    public User()
    {
        this.Registers = new ObservableCollection<Register>();
    }

    public void addRegisterAccess(Register register)
    {
        Registers.Add(register);
    }
}

当一个寄存器被创建时,它被添加到寄存器table,然后被添加到这个列表,完成如下:

//Set the register to the updated version of this register that is stored on db, 
//as current register that has been created through user input does not have an ID.
register = database.db.GetRegisterByNameAndLocation(register.Name, register.Location);

//Add the register to the current user list of registers. Then fetch the new info and set the current user
// from the db.
database.db.GetUserByEmail(currentUser.user.emailAddress).addRegisterAccess(register);

当我尝试通过用户对象访问寄存器列表时,它说该列表不包含任何元素。

我四处寻找解决方案,他们似乎提到了 SQLite UpdateWithChildren,但这种方法不存在于我的 SQLite 连接或我的数据库中。寄存器列表是一个ManyToMany关系,更新如何适应所有这些?

**编辑:**我现在有了更新方法,但似乎在它被击中时出现异常。下面是我的 'DatabaseManager' 中将注册添加到用户列表的方法:

public void addRegisterAccess(User user, Register register)
    {
        user.Registers.Add(register);
        _connection.InsertOrReplaceWithChildren(user, true);
    }

添加寄存器时出现以下异常,我认为link classes(使用中间table)的代码不需要用户调用代码?

    02-10 12:09:51.662 E/AndroidRuntime( 4461): Caused by: md52ce486a14f4bcd95899665e9d932190b.JavaProxyThrowable: SQLiteNetExtensions.Exceptions.IncorrectRelationshipException: User.Registers: ManyToMany relationship origin must have a foreign key defined in the intermediate type
02-10 12:09:51.662 E/AndroidRuntime( 4461):   at SQLiteNetExtensions.Extensions.WriteOperations.Assert (Boolean assertion, System.Type type, System.Reflection.PropertyInfo property, System.String message) <0xd84bb6e8 + 0x00087> in <filename unknown>:0 
02-10 12:09:51.662 E/AndroidRuntime( 4461):   at SQLiteNetExtensions.Extensions.WriteOperations.UpdateManyToManyForeignKeys (SQLite.Net.SQLiteConnection conn, System.Object element, System.Reflection.PropertyInfo relationshipProperty) <0xd84b9750 + 0x0026b> in <filename unknown>:0 
02-10 12:09:51.662 E/AndroidRuntime( 4461):   at SQLiteNetExtensions.Extensions.WriteOperations.UpdateInverseForeignKeys (SQLite.Net.SQLiteConnection conn, System.Object element) <0xd84b9578 + 0x0014f> in <filename unknown>:0 
02-10 12:09:51.662 E/AndroidRuntime( 4461):   at SQLiteNetExtensions.Extensions.WriteOperations.UpdateWithChildren (SQLite.Net.SQLiteConnection conn, System.Object element) <0xd84b8a68 + 0x0003b> in <filename unknown>:0 
02-10 12:09:51.662 E/AndroidRuntime( 4461):   at SQLiteNetExtensions.Extensions.WriteOperations.InsertWithChildrenRecursive (SQLite.Net.SQLiteConnection conn, System.Object element, Boolean replace, Boolean recursive, ISet`1 objectCache) <0xd84b76f8 + 0x000af> in <filename unknown>:0 
02-10 12:09:51.662 E/AndroidRuntime( 4461):   at SQLiteNetExtensions.Extensions.WriteOperations.InsertOrReplaceWithChildren (SQLite.Net.SQLiteConnection conn, System.Object element, Boolean recursive) <0xd84b76a8 + 0x0002f> in <filename unknown>:0 
02-10 12:09:51.662 E/AndroidRuntime( 4461):   at RegistrationApp.Data.DatabaseManager.addRegisterAccess (RegistrationApp.User user, RegistrationApp.Models.Register register) <0xd84b7578 + 0x0003f> in <filename unknown>:0 
02-10 12:09:51.662 E/AndroidRuntime( 4461):   at RegistrationApp.CreateRegisterPage+<OnCreateButtonClicked>d__1b.MoveNext () <0xd87ad788 + 0x006c3> in <filename unknown>:0 
02-10 12:09:51.662 E/AndroidRuntime( 4461): --- End of stack trace from previous location where exception was thrown ---

补充一下,我的中级 table class 看起来像这样:

public class RegUser
    {
        [ForeignKey(typeof(User))]
        public int UserID { get; set; }

        [ForeignKey(typeof(Register))]
        public int RegisterID { get; set; }
    }

**编辑:** 下面是寄存器 Class 本身:

public class Register
    {
        [PrimaryKey, AutoIncrement]
        public int RegisterID { get; set; }
        public string Name { get; set; }
        public string Type { get; set; }
        public string Location { get; set; }
        public DateTime Date { get; set; }
        public string StartTime { get; set; }
        public string EndTime { get; set; }
        public Boolean Recurring { get; set; }

        [ManyToMany(typeof(RegStudent), "StudentID", "Registers")]
        public ObservableCollection<KeyValuePair<Student, string>> StudentList { get; set; }

        [ManyToMany(typeof(RegUser), "UserID", "Registers")]
        public ObservableCollection<User> UserList { get; set; }

        public Register()
        {
            this.StudentList = new ObservableCollection<KeyValuePair<Student, string>>();
            this.UserList = new ObservableCollection<User>();
        }

        //Adds a student to the Student List for this register, marking the string value as '-', to show the register has not been taken yet.
        //This value will be set to the status of the student, to show them as Present, AWOL, Sick, Late, etc.
        public void addStudent(Student student)
        {
            StudentList.Add(new KeyValuePair<Student, string>(student, "-"));
        }
    } 

您正在创建 KeyValuePair 的列表,因此出现 KeyValuePair 没有主键的错误:

[ManyToMany(typeof(RegStudent), "StudentID", "Registers")]
public ObservableCollection<KeyValuePair<Student, string>> StudentList { get; set; }

将其更改为 Student 的列表:

[ManyToMany(typeof(RegStudent), "StudentID", "Registers")]
public ObservableCollection<Student> StudentList { get; set; }

如果你需要在关系中存储信息,你应该将它存储在RegUser class:

public class RegUser
{
    [ForeignKey(typeof(User))]
    public int UserID { get; set; }

    [ForeignKey(typeof(Register))]
    public int RegisterID { get; set; }

    public string Status { get; set; }
}

请注意,SQLite-Net Extensions 目前不支持中间表中的其他属性,您必须手动获取该信息:

var regUser = conn.Table<RegUser>.Where(ru => ru.UserID == user.ID && ru.RegisterID == register.ID).FirstOrDefault();
if (regUser != null) {
    var status = regUser.Status;
}