2017-06-21 83 views
1

我使用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而沒有成功。

編輯

我安裝​​,改變了代碼示例

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-PCLoysteinkrog)是sqlite-net-pclpraeclarum)的叉子。看起來後者與SQLite-Net Extensions不兼容,這正是我需要的。但是SQLite.Net-PCL支持UWP嗎?它自2016年6月4日起未更新。最有趣的是SQLite-Net Extensions鏈接到praeclarum,這是錯誤的。我通過卸載所有的SQL Nuget包來檢查這一點,只安裝SQLite-Net Extensions,它應該自動觸發所需的依賴關係。我能做什麼?

+1

不要在你的問題中討論投票。無論如何,我猜你應該讀[問]幷包括實際的錯誤。 「發生一個或多個錯誤」是一個AggregateException,其中包含發生在其「InnerExceptions」屬性中的實際異常。這些例外包含您可以進一步研究的信息,並且不要忘記在您的問題中展示您的研究。 – CodeCaster

+1

請參閱示例[我可以在SQLite類中使用字符串列表嗎?](https://stackoverflow.com/questions/14663984/can-i-use-a-list-of-string-in-a -class意圖的換源碼)。 – CodeCaster

+0

我嘗試過使用'SQLiteNetExtensions',但是我得到了列表中的相同錯誤(請參閱編輯的問題)。不應該有可能使用'ForeignKey'將對象嵌套到對象中? – testing

回答

0

爲了能夠使用嵌套Listobject我需要SQLiteNetExtensions。因爲我使用another SQLite packageSQLiteNetExtensionsdefault dependency你有兩個選擇:

  1. 手動將項目添加到您的解決方案
    1.1。下載SQLiteNetExtensions的源代碼
    1.2。作爲項目「SQLiteNetExtensions-PCL」添加到您的解決方案
    1.3。添加這個項目作爲參考所有項目(便攜,的iOS,Droid的,UWP)

  2. Install SQLiteNetExtensions 2.0.0-alpha2

要知道,如果你已經安裝了一些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]關係。

要使用對象,你應該能夠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; } 
} 

一個很好的指導如何使用[OneToOne]關係的工作(例如,針對對象)是this here。對於[OneToMany]看起來here

還有一些更多的步驟,如創建表格,以特殊方式檢索和存儲數據(GetWithChildrenUpdateWithChildren,...)。也請注意CascadeOperations,如果您有多層次的水印,您將需要這些。