2017-06-21 4 views
1

J'utilise SQLite as a database et je le tableau suivant, qui fonctionne, quand je le crée:Comment travailler avec des classes et des listes imbriquées dans ma table?

public class TodoItem 
{ 
    [PrimaryKey, AutoIncrement] 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Notes { get; set; } 
    public bool Done { get; set; } 
    public Gender Gender { get; set; } 
    public DateTime? DateOfBirth { get; set; } 
} 

Lors de la création de la table

database.CreateTableAsync<TodoItem>().Wait(); 

maintenant je reçois des erreurs, si je veux d'inclure un objet imbriqué:

public class Test 
{ 
    [PrimaryKey, AutoIncrement] 
    public int AnotherID { get; set; } 
    public string Name { get; set; } 
} 
public class TodoItem 
{ 
    [PrimaryKey, AutoIncrement] 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Notes { get; set; } 
    public bool Done { get; set; } 
    public Gender Gender { get; set; } 
    public DateTime? DateOfBirth { get; set; } 
    public Test Test { get; set; } 
} 

Je reçois l'erreur suivante

UNHANDLED EXCEPTION: 
System.AggregateException: One or more errors occurred. ---> System.NotSupportedException: Don't know about Todo.Test 
    at SQLite.Orm.SqlType (SQLite.TableMapping+Column p, System.Boolean storeDateTimeAsTicks) [0x001ad] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2080 
    at SQLite.Orm.SqlDecl (SQLite.TableMapping+Column p, System.Boolean storeDateTimeAsTicks) [0x00000] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2027 
    at SQLite.SQLiteConnection.<CreateTable>m__0 (SQLite.TableMapping+Column p) [0x00000] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:417 
    at System.Linq.Enumerable+SelectArrayIterator`2[TSource,TResult].ToArray() [0x00012] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/external/corefx/src/System.Linq/src/System/Linq/Select.cs:251 
    at System.Linq.Enumerable.ToArray[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x00015] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/external/corefx/src/System.Linq/src/System/Linq/ToCollection.cs:19 
    at SQLite.SQLiteConnection.CreateTable (System.Type ty, SQLite.CreateFlags createFlags) [0x00133] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:418 
    at SQLite.SQLiteAsyncConnection+<CreateTablesAsync>c__AnonStorey0.<>m__0() [0x0002f] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLiteAsync.cs:108 
    at System.Threading.Tasks.Task`1[TResult].InnerInvoke() [0x0000f] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Future.cs:680 
    at System.Threading.Tasks.Task.Execute() [0x00010] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502 
    --- End of inner exception stack trace --- 
    at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:2157 
    at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) [0x00043] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:3189 
    at System.Threading.Tasks.Task.Wait() [0x00000] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:3054 
    at Todo.TodoItemDatabase..ctor (System.String dbPath) [0x00015] in C:\Users\some-user\Documents\Visual Studio 2015\Projects\Todo\Todo\Data\TodoItemDatabase.cs:14 
    at Todo.App.get_Database() [0x0000e] in C:\Users\some-user\Documents\Visual Studio 2015\Projects\Todo\Todo\App.cs:32 
    at Todo.TodoListPage+<OnAppearing>d__1.MoveNext() [0x0002c] in C:\Users\some-user\Documents\Visual Studio 2015\Projects\Todo\Todo\Views\TodoListPage.xaml.cs:20 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:151 
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1018 
    at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0() [0x00000] in /Users/builder/data/lanes/4695/448f54fd/source/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:35 
    at Java.Lang.Thread+RunnableImplementor.Run() [0x00008] in /Users/builder/data/lanes/4695/448f54fd/source/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36 
    at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/builder/data/lanes/4695/448f54fd/source/xamarin-android/src/Mono.Android/obj/Release/android-23/mcw/Java.Lang.IRunnable.cs:81 
    at (wrapper dynamic-method) System.Object:4ad81135-c1dd-4bba-bca3-4e991f58da69 (intptr,intptr) 
---> (Inner Exception #0) System.NotSupportedException: Don't know about Todo.Test 
    at SQLite.Orm.SqlType (SQLite.TableMapping+Column p, System.Boolean storeDateTimeAsTicks) [0x001ad] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2080 
    at SQLite.Orm.SqlDecl (SQLite.TableMapping+Column p, System.Boolean storeDateTimeAsTicks) [0x00000] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2027 
    at SQLite.SQLiteConnection.<CreateTable>m__0 (SQLite.TableMapping+Column p) [0x00000] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:417 
    at System.Linq.Enumerable+SelectArrayIterator`2[TSource,TResult].ToArray() [0x00012] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/external/corefx/src/System.Linq/src/System/Linq/Select.cs:251 
    at System.Linq.Enumerable.ToArray[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x00015] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/external/corefx/src/System.Linq/src/System/Linq/ToCollection.cs:19 
    at SQLite.SQLiteConnection.CreateTable (System.Type ty, SQLite.CreateFlags createFlags) [0x00133] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:418 
    at SQLite.SQLiteAsyncConnection+<CreateTablesAsync>c__AnonStorey0.<>m__0() [0x0002f] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLiteAsync.cs:108 
    at System.Threading.Tasks.Task`1[TResult].InnerInvoke() [0x0000f] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Future.cs:680 
    at System.Threading.Tasks.Task.Execute() [0x00010] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502 <--- 

Si j'utilise un List

public class TodoItem 
{ 
    [PrimaryKey, AutoIncrement] 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Notes { get; set; } 
    public bool Done { get; set; } 
    public Gender Gender { get; set; } 
    public DateTime? DateOfBirth { get; set; } 
    public List<string> Strings { get; set; } 
} 

Je reçois

UNHANDLED EXCEPTION: 
System.AggregateException: One or more errors occurred. ---> System.NotSupportedException: Don't know about System.Collections.Generic.List`1[System.String] 
    at SQLite.Orm.SqlType (SQLite.TableMapping+Column p, System.Boolean storeDateTimeAsTicks) [0x001ad] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2080 
    at SQLite.Orm.SqlDecl (SQLite.TableMapping+Column p, System.Boolean storeDateTimeAsTicks) [0x00000] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2027 
    at SQLite.SQLiteConnection.<CreateTable>m__0 (SQLite.TableMapping+Column p) [0x00000] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:417 
    at System.Linq.Enumerable+SelectArrayIterator`2[TSource,TResult].ToArray() [0x00012] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/external/corefx/src/System.Linq/src/System/Linq/Select.cs:251 
    at System.Linq.Enumerable.ToArray[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x00015] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/external/corefx/src/System.Linq/src/System/Linq/ToCollection.cs:19 
    at SQLite.SQLiteConnection.CreateTable (System.Type ty, SQLite.CreateFlags createFlags) [0x00133] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:418 
    at SQLite.SQLiteAsyncConnection+<CreateTablesAsync>c__AnonStorey0.<>m__0() [0x0002f] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLiteAsync.cs:108 
    at System.Threading.Tasks.Task`1[TResult].InnerInvoke() [0x0000f] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Future.cs:680 
    at System.Threading.Tasks.Task.Execute() [0x00010] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502 
    --- End of inner exception stack trace --- 
    at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:2157 
    at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) [0x00043] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:3189 
    at System.Threading.Tasks.Task.Wait() [0x00000] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:3054 
    at Todo.TodoItemDatabase..ctor (System.String dbPath) [0x00015] in C:\Users\some-user\Documents\Visual Studio 2015\Projects\Todo\Todo\Data\TodoItemDatabase.cs:14 
    at Todo.App.get_Database() [0x0000e] in C:\Users\some-user\Documents\Visual Studio 2015\Projects\Todo\Todo\App.cs:32 
    at Todo.TodoListPage+<OnAppearing>d__1.MoveNext() [0x0002c] in C:\Users\some-user\Documents\Visual Studio 2015\Projects\Todo\Todo\Views\TodoListPage.xaml.cs:20 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:151 
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1018 
    at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0() [0x00000] in /Users/builder/data/lanes/4695/448f54fd/source/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:35 
    at Java.Lang.Thread+RunnableImplementor.Run() [0x00008] in /Users/builder/data/lanes/4695/448f54fd/source/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36 
    at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/builder/data/lanes/4695/448f54fd/source/xamarin-android/src/Mono.Android/obj/Release/android-23/mcw/Java.Lang.IRunnable.cs:81 
    at (wrapper dynamic-method) System.Object:3ff99a1f-7842-4c41-b229-386570e8d19f (intptr,intptr) 
---> (Inner Exception #0) System.NotSupportedException: Don't know about System.Collections.Generic.List`1[System.String] 
    at SQLite.Orm.SqlType (SQLite.TableMapping+Column p, System.Boolean storeDateTimeAsTicks) [0x001ad] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2080 
    at SQLite.Orm.SqlDecl (SQLite.TableMapping+Column p, System.Boolean storeDateTimeAsTicks) [0x00000] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2027 
    at SQLite.SQLiteConnection.<CreateTable>m__0 (SQLite.TableMapping+Column p) [0x00000] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:417 
    at System.Linq.Enumerable+SelectArrayIterator`2[TSource,TResult].ToArray() [0x00012] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/external/corefx/src/System.Linq/src/System/Linq/Select.cs:251 
    at System.Linq.Enumerable.ToArray[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x00015] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/external/corefx/src/System.Linq/src/System/Linq/ToCollection.cs:19 
    at SQLite.SQLiteConnection.CreateTable (System.Type ty, SQLite.CreateFlags createFlags) [0x00133] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:418 
    at SQLite.SQLiteAsyncConnection+<CreateTablesAsync>c__AnonStorey0.<>m__0() [0x0002f] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLiteAsync.cs:108 
    at System.Threading.Tasks.Task`1[TResult].InnerInvoke() [0x0000f] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Future.cs:680 
    at System.Threading.Tasks.Task.Execute() [0x00010] in /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502 <--- 

J'utilise SQLite-net Official Portable Library 1.3.3. Dois-je utiliser des attributs comme PrimaryKey, ForeignKey et ainsi de suite? Comment? Ou la bibliothèque est-elle seulement capable de gérer les types de données primitifs?

L'échantillon peut être téléchargé à partir de here.

This issue indique qu'il devrait être possible de travailler avec List, mais pas dans la dernière version. J'ai essayé de rétrograder à 1.2.0 et 1.3.1 sans succès.

Modifier

J'ai installé SQLiteNetExtensions et changé l'exemple de code à

using SQLite; 
using SQLiteNetExtensions.Attributes; 
using System.Collections.Generic; 

namespace Todo 
{ 
    public class Test 
    { 
     [PrimaryKey, AutoIncrement] 
     public int AnotherID { get; set; } 
     public string Name { get; set; } 
    } 

    public class TodoItem 
    { 
     [PrimaryKey, AutoIncrement] 
     public int ID { get; set; } 
     public string Name { get; set; } 
     public string Notes { get; set; } 
     public bool Done { get; set; } 
     [TextBlob("StringsBlobbed")] 
     public List<string> Strings { get; set; } 
     public string StringsBlobbed { get; set; } 
    } 
} 

et je reçois toujours la même erreur.

Edit 2

Je pense qu'il ya une confusion entre bibliothèques. SQLite-Net Extensions dépend de SQLite.Net-PCL v. 3.1.1 (Nuget). Mais Xamarin lié à la bibliothèque sqlite-net-pcl v. 1.3.3 (Nuget).

SQLite.Net-PCL (oysteinkrog) est une fourche de sqlite-net-pcl (praeclarum). Il semble que ce dernier n'est pas compatible avec SQLite-Net Extensions, ce dont j'ai besoin ici. Mais est-ce que SQLite.Net-PCL prend en charge UWP? Il n'a pas été mis à jour depuis le 4 juin 2016. Et la chose la plus drôle est que SQLite-Net Extensions liens à praeclarum, ce qui est faux. J'ai vérifié ceci en désinstallant tous les paquets de Nuget de SQL et en installant seulement SQLite-Net Extensions, qui devrait déclencher les dépendances requises automatiquement. Que puis-je faire?

+1

Ne discutez pas des votes dans votre question. Quoi qu'il en soit, je suppose que vous devriez lire [demander] et inclure l'erreur réelle. "Une ou plusieurs erreurs sont survenues" est une exception AggregateException, qui contient les exceptions réelles survenues dans sa propriété 'InnerExceptions'. Ces exceptions contiennent des messages que vous pouvez approfondir, et n'oubliez pas de montrer votre recherche dans votre question. – CodeCaster

+1

Voir par exemple [Puis-je utiliser une liste de chaînes dans une classe destinée à SQLite?] (Https://stackoverflow.com/questions/14663984/can-i-use-a-list-of-string-in-a -class-destiné-à-sqlite). – CodeCaster

+0

J'ai essayé d'utiliser 'SQLiteNetExtensions', mais j'ai la même erreur pour la liste (voir question éditée). Ne devrait-il pas être possible de travailler avec 'ForeignKey' pour imbriquer un objet dans un objet? – testing

Répondre

0

Pour pouvoir travailler avec un List imbriqué ou object j'ai besoin de SQLiteNetExtensions.Parce que j'utilise another SQLite package que le default dependency de SQLiteNetExtensions vous avez deux options:

  1. ajouter manuellement le projet à votre solution
    1.1. Télécharger la source de SQLiteNetExtensions
    1.2. Ajouter comme projet "SQLiteNetExtensions-PCL" à votre solution
    1.3. Ajouter ce projet comme référence à tous vos projets (portable, iOS, Droid, UWP)

  2. Install SQLiteNetExtensions 2.0.0-alpha2

Attention si vous avez déjà installé certains paquets de NuGet sql. Désinstallez-les d'abord, puis installez uniquement SQLiteNetExtensions. Cela ajoutera toutes les dépendances requises pour vous.

Pour List<string> vous pouvez faire:

public class TodoItem 
{ 
    [PrimaryKey, AutoIncrement] 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Notes { get; set; } 
    public bool Done { get; set; } 

    [TextBlob("StringsBlobbed")] 
    public List<string> Strings { get; set; } 
    public string StringsBlobbed { get; set; } 
} 

Si vous avez d'autres types de listes dont vous avez besoin d'une relation [OneToMany].

Pour travailler avec des objets que vous devriez être en mesure to do this:

public class Test 
{ 
    [PrimaryKey, AutoIncrement] 
    public string AnotherID { get; set; } 
    public string Name { get; set; } 
} 

public class TodoItem 
{ 
    [PrimaryKey, AutoIncrement] 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Notes { get; set; } 
    public bool Done { get; set; } 

    [ForeignKey(typeof(Test))] 
    public string TestId { get; set; } 

    [OneToOne] 
    public Test Test { get; set; } 
} 

Un bon guide comment travailler avec [OneToOne] relations (par exemple pour les objets) est this here. Pour [OneToMany], regardez here.

Il existe d'autres étapes telles que la création de la table et la récupération et le stockage des données d'une manière spéciale (GetWithChildren, UpdateWithChildren, ...). Tenez également compte du CascadeOperations, dont vous aurez besoin si vous avez une hiérarchie à plusieurs niveaux.