J'utilise Xamarin et C# pour créer une application multi-plateforme. Les extensions SQLite.Net sont utilisées pour la base de données locale. Le tableau de l'utilisateur contient une liste de registres, comme on le voit ci-dessous:Les éléments que vous avez enregistrés sont vides lors de la récupération à un moment ultérieur.
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);
}
}
Lorsqu'un registre est fait, il est ajouté à la table de registre, puis ajouté à cette liste, fait comme ci-dessous:
//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);
Lorsque j'essaie d'accéder à la liste des registres, via l'objet utilisateur, il indique que la liste ne contient aucun élément.
J'ai cherché des solutions et elles semblent mentionner le SQLite UpdateWithChildren
, mais cette méthode n'est pas celle qui existe dans ma connexion SQLite ou dans ma base de données. La liste des registres est une relation ManyToMany
, comment la mise à jour s'intègre-t-elle à tout cela?
** EDIT: ** J'ai maintenant la méthode de mise à jour, mais semble obtenir une exception quand il est frappé. Ci-dessous la méthode dans mon « DatabaseManager » qui ajoute un registre à une liste d'utilisateurs:
public void addRegisterAccess(User user, Register register)
{
user.Registers.Add(register);
_connection.InsertOrReplaceWithChildren(user, true);
}
L'exception ci-dessous est donnée lorsqu'un registre est ajouté, je pensais que le code pour lier les classes (avec table intermédiaire) a fait pas besoin d'être appelé par le code utilisateur?
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 ---
Juste pour ajouter, ma classe de table intermédiaire ressemble à ceci:
public class RegUser
{
[ForeignKey(typeof(User))]
public int UserID { get; set; }
[ForeignKey(typeof(Register))]
public int RegisterID { get; set; }
}
** EDIT: ** Ci-dessous le registre classe elle-même:
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, "-"));
}
}
Essayez d'ajouter 'using SQLiteNetExtensions.Extensions;' pour rendre la méthode UpdateWithChildren disponible. – redent84
@ redent84 Je ne peux pas croire que j'ai raté ça. J'ai utilisé la méthode mais elle donne une exception que je n'ai pas vue auparavant. J'ai mis à jour à la question pour montrer le code et l'exception. – user2283597
@ redent84 J'essayais d'utiliser 'InsertOrUpdateWithChildren' mais j'ai essayé d'utiliser' UpdateWithChildren' à la place. Je reçois maintenant une exception différente, celle qui dit 'SQLiteNetExtensions.Exceptions.IncorrectRelationshipException: Register.StudentList: ManyToMany destination de la relation doit avoir la clé primaire' ... la seule solution que j'ai pu trouver en ligne n'a pas aidé à résoudre ce problème. Toute idée où je devrais chercher pour empêcher l'excpetion? Merci pour l'aide – user2283597