如何使用我的表中的嵌套类和列表?

时间:2017-06-21 09:48:35

标签: c# sqlite xamarin sqlite-net sqlite-net-extensions

我使用SQLite as a database并且我有下表,当我创建它时,它有效:

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

创建表

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

现在我遇到一些错误,如果我想要包含一个嵌套对象:

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

我收到以下错误

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

如果我使用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; }
}

我得到了

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

我正在使用SQLite-net Official Portable Library 1.3.3 。我是否必须使用PrimaryKeyForeignKey等属性?怎么样?或者该库是否只能处理原始数据类型?

可以从here下载样本。

This issue表示,应该可以使用List,但不能使用最新版本。我试图降级到1.2.0和1.3.1而没有成功。

修改

我安装了SQLiteNetExtensions并将示例代码更改为

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

我仍然得到同样的错误。

修改2

我认为图书馆之间存在混淆。 SQLite-Net Extensions取决于SQLite.Net-PCL v. 3.1.1Nuget)。但是Xamarin链接到了库sqlite-net-pcl v. 1.3.3Nuget)。

SQLite.Net-PCL oysteinkrog )是sqlite-net-pcl praeclarum )的分支。似乎后者与SQLite-Net Extensions不兼容,这就是我在这里所需要的。但SQLite.Net-PCL是否支持UWP?它自2016年6月4日起尚未更新。最有趣的是SQLite-Net Extensions链接到praeclarum,这是错误的。我通过卸载所有SQL Nuget软件包并仅安装SQLite-Net Extensions来检查这一点,这应该会自动触发所需的依赖项。我该怎么办?

1 个答案:

答案 0 :(得分:1)

能够使用嵌套的Listobject我需要SQLiteNetExtensions。因为我使用another SQLite package而不是SQLiteNetExtensions的{​​{3}},您有两种选择:

  1. 手动将项目添加到您的解决方案中 1.1。下载SQLiteNetExtensions的来源 1.2。添加为项目&#34; SQLiteNetExtensions-PCL&#34;对你的解决方案
    1.3。添加此项目作为所有项目的参考(便携式,iOS,Droid,UWP)

  2. default dependency

  3. 请注意您是否已经安装了一些sql NuGet包。首先卸载所有这些,然后只安装SQLiteNetExtensions。这将为您添加所有必需的依赖项。

    对于List<string>,你可以这样做:

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

    如果您有其他类型的列表,则需要[OneToMany]关系。

    要处理对象,您应该能够Install SQLiteNetExtensions 2.0.0-alpha2

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

    如何使用[OneToOne]关系(例如对象)的良好指南是to do this。对于[OneToMany]this here

    还有一些步骤,比如创建表格,以及以特殊方式检索和存储数据(GetWithChildrenUpdateWithChildren,...)。还要注意here,如果你有多层次的hirarchy,你将需要它。