Xamarin.Android SQLite.NET doppelter Spaltenname: ID

Arbeite ich mit Xamarin cross-Plattform-Datenbank mit SQLite und die folgende Ausnahme wird geworfen nur, wenn auf release-Modus. Diese exception wird nie geworfen, die auf den debug-Modus.

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)

Das Modell ist wie folgt definiert:

public class FailedUpload
{
    [PrimaryKey, AutoIncrement]
    public int ID { get; set; }

    [NotNull]
    public string Path { get; set; }

    [NotNull]
    public string FolderHash { get; set; }

    public FailedUpload () {}

    public FailedUpload (string path, string folderHash) {
        Path = path;
        FolderHash = folderHash;
    }
}

Habe ich Folgendes definiert die Schnittstelle und implementiert es in mein Android-Projekt:

public interface ISQLite
{
    SQLiteConnection Connection { get; }
    void Delete ();
}

Dann nutze ich die Abhängigkeit Dienst Zugriff auf die Datenbank:

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

}

Sollte ich etwas bestimmtes, um zu verhindern, dass die Ausnahme im release-Modus, oder einfach nur fangen und nichts tun, oder ist es ein bug in Xamarin oder SQLite?



One Reply
  1. 4

    Werden Sie eventuell vor einer (falschen) Optimierung, verursacht durch den linker. Wenn Sie noch nie die Referenz ID Eigenschaft von code, der linker entfernt.
    Sie können dies vermeiden, indem Sie hinzufügen einer [Preserve] Attribut.

    Dieses Attribut ist nicht verfügbar in PCLs aber die linker der nur daran interessiert ist das Attribut name, so fügen Sie einfach die folgende Klasse, um Ihre 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()
        {
        }
    }

    Außerdem: warum verwenden Sie eine Schnittstelle zu injizieren Sqlite.Net? Es ist bereits funktionierende cross-Plattform und auch innerhalb eines PCL. Alles, was Sie brauchen, ist der Pfad zu der Datenbank. Siehe: https://developer.xamarin.com/guides/xamarin-forms/working-with/databases/#XamarinForms_PCL_Project

    • Die Schnittstelle wurde eigentlich erstellt, um Datenbank-Pfad auf jeder Plattform (ich habe die genaue Anleitung, die Sie zur Verfügung gestellt). Es hat auch eine Delete () – Funktion für Entwicklungszwecke.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.