C# Android SQLite.NET重复列名:ID

C# Android SQLite.NET重复列名:ID,c#,android,sqlite,xamarin,C#,Android,Sqlite,Xamarin,我正在用SQLite处理Xamarin跨平台数据库,只有在发布模式下才会抛出以下异常。在调试模式下不会引发此异常 Xamarin caused by: android.runtime.JavaProxyThrowable: SQLite.SQLiteException: duplicate column name: ID at SQLite.SQLite3.Prepare2 (SQLitePCL.sqlite3 db, System.String query) <0xa02a0d48

我正在用SQLite处理Xamarin跨平台数据库,只有在发布模式下才会抛出以下异常。在调试模式下不会引发此异常

Xamarin caused by: android.runtime.JavaProxyThrowable: SQLite.SQLiteException: duplicate column name: ID
  at SQLite.SQLite3.Prepare2 (SQLitePCL.sqlite3 db, System.String query) <0xa02a0d48 + 0x0005c> in <filename unknown>:0 
  at SQLite.SQLiteCommand.Prepare () <0xa02a0cc0 + 0x00023> in <filename unknown>:0 
  at SQLite.SQLiteCommand.ExecuteNonQuery () <0xa02a0a28 + 0x00023> in <filename unknown>:0 
  at SQLite.SQLiteConnection.Execute (System.String query, System.Object[] args) <0xa02a0548 + 0x0009f> in <filename unknown>:0 
  at SQLite.SQLiteConnection.MigrateTable (SQLite.TableMapping map) <0xa02a2bb8 + 0x00213> in <filename unknown>:0 
  at SQLite.SQLiteConnection.CreateTable (System.Type ty, CreateFlags createFlags) <0x9f25f170 + 0x004af> in <filename unknown>:0 
  at SQLite.SQLiteConnection.CreateTable[T] (CreateFlags createFlags) <0x9f25f0c0 + 0x0002b> in <filename unknown>:0 
  at lv.app.shared.DB.FailedUploadDBConn..ctor () <0x9f25a200 + 0x0005f> in <filename unknown>:0 
  at lv.app.android.services.InstantUploadService.OnCreate () <0x9f25a048 + 0x00027> in <filename unknown>:0 
  at Android.App.Service.n_OnCreate (IntPtr jnienv, IntPtr native__this) <0x9f259fe0 + 0x00037> in <filename unknown>:0 
  at (wrapper dynamic-method) System.Object:77405489-155e-4e61-bb78-110dfea670a3 (intptr,intptr)
    at md56f5b51080823ac84a85e457b8b35670a.InstantUploadService.n_onCreate(Native Method)
    at md56f5b51080823ac84a85e457b8b35670a.InstantUploadService.onCreate(InstantUploadService.java:30)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3280)
    at android.app.ActivityThread.access$1900(ActivityThread.java:181)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1565)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:145)
    at android.app.ActivityThread.main(ActivityThread.java:6145)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
我已经定义了以下接口并在我的Android项目中实现了它:

public interface ISQLite
{
    SQLiteConnection Connection { get; }
    void Delete ();
}
然后我使用依赖项服务访问数据库:

public class FailedUploadDBConn
{
    SQLite.SQLiteConnection conn;

    public FailedUploadDBConn () {
        var dependency = DependencyService.Get<ISQLite> ();
        conn = dependency.Connection;
        conn.CreateTable<FailedUpload> (); //Exception gets thrown here.
    }

    //Other methods...

}
公共类失败PloaddbConn
{
SQLite.SQLite连接连接;
公共故障PloaddbConn(){
var dependency=DependencyService.Get();
conn=依赖关系。连接;
conn.CreateTable();//在此处引发异常。
}
//其他方法。。。
}
我应该做一些特定的事情来防止在发布模式下出现异常,还是只捕获异常而不做任何事情,或者这是Xamarin或SQLite中的一个bug?

您可能会面临由链接器引起的(不正确的)优化。如果从未从代码中引用
ID
属性,则链接器会将其删除。 您可以通过添加
[Preserve]
来防止这种情况

此属性在PCL中不可用,但只对属性的名称感兴趣,因此只需将以下类添加到PCL中:

[AttributeUsage(AttributeTargets.All)]
public class PreserveAttribute : Attribute
{
    public bool AllMembers;
    public bool Conditional;

    public PreserveAttribute(bool allMembers, bool conditional)
    {
        AllMembers = allMembers;
        Conditional = conditional;
    }

    public PreserveAttribute()
    {
    }
}
此外:为什么要使用接口来注入Sqlite.Net?它已经在跨平台工作,也在PCL内部工作。您所需要的只是数据库的路径。请参阅:

您可能面临由链接器导致的(不正确)优化。如果从未从代码中引用
ID
属性,则链接器会将其删除。 您可以通过添加
[Preserve]
来防止这种情况

此属性在PCL中不可用,但只对属性的名称感兴趣,因此只需将以下类添加到PCL中:

[AttributeUsage(AttributeTargets.All)]
public class PreserveAttribute : Attribute
{
    public bool AllMembers;
    public bool Conditional;

    public PreserveAttribute(bool allMembers, bool conditional)
    {
        AllMembers = allMembers;
        Conditional = conditional;
    }

    public PreserveAttribute()
    {
    }
}

此外:为什么要使用接口来注入Sqlite.Net?它已经在跨平台工作,也在PCL内部工作。您所需要的只是数据库的路径。请参阅:

创建该接口实际上是为了在每个平台上提供数据库路径(我遵循了您提供的确切指南)。它还有一个Delete()函数用于开发目的。实际上,创建该接口是为了在每个平台上提供数据库路径(我遵循了您提供的确切指南)。它还有一个Delete()函数用于开发。