0

を使用するXamarin.FormsアプリSQLite.Netでは、次のコードが機能します。

public class MyClass
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    [MaxLength(45)]
    public string Name { get; set; }
}

ただし、AutoIncrement属性を削除すると、2 番目database.Insertに Constraint 型の SQLiteException が発生します (シミュレーターをリセットした後でも)。

ただし、https: //www.sqlite.org/autoinc.html にある SQLite のドキュメントでは、パフォーマンス上の理由から、AutoIncrement可能な限り避けるべきであると強調しています。AutoIncrementドキュメントは、を使用して回避できることを示唆していますrowIdrowIDSQLite.Netにアクセスする方法はありますか?

******** 編集: ******** 例外のテキストは次のとおりです。

In Main DatabaseException: In OnStart DatabaseException: In Initialise  DatabaseException: In UpsertAsync<T>  ---> SQLite.Net.SQLiteException: Constraint
at SQLite.Net.PreparedSqlLiteInsertCommand.ExecuteNonQuery (System.Object[] source) [0x00000] in <filename unknown>:0 
at SQLite.Net.SQLiteConnection.Insert (System.Object obj, System.String extra, System.Type objType) [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---

私の挿入コードは次のとおりです。

db = DependencyService.Get<ISQLite> ().GetAsyncConnection ();
MyClass mc = new MyClass()
{
    Name = "Hello World!"
};
await UpsertAsync<MyClass> ( mc );
...
...

public async Task<int> UpsertAsync<T> (T row)
// Update a row, of if the row does not exist then insert it
// Returns the Id of the row
{
    try
    {   
        using (IDisposable releaser = await locker.LockAsync ()) 
        {
            Type t = row.GetType ();
            int rowId = Convert.ToInt32 ((t.GetRuntimeProperty("Id")).GetValue (row));      // Get row.Id at runtime using PropertyInfo
            if (rowId != 0) 
            {
                await db.UpdateAsync (row).ConfigureAwait(continueOnCapturedContext:false);
                return rowId;
            } 
            else 
            {
                await db.InsertAsync (row).ConfigureAwait(continueOnCapturedContext:false);
                rowId = Convert.ToInt32 ((t.GetRuntimeProperty ("Id")).GetValue (row));
                return rowId;
            }
        }
    }
    catch (Exception ex)
    {
        throw new DatabaseException ( "In UpsertAsync<T> ", ex);
    }
}

これは、 が存在しない場合に例外を取得し、 でAutoIncrement正しく動作しAutoIncrementます。

注: インデックスがある場合は 1 から始まり、AutoIncrementない場合は 0 から始まるようです。これにより、Upsert コードにバグがあり、 がrowId存在しない場合に 0 をテストしますAutoIncrementが、そのバグはこの問題とは関係ありません。

4

0 に答える 0