在使用 的Xamarin.Forms
应用程序中SQLite.Net
,以下代码有效:
public class MyClass
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[MaxLength(45)]
public string Name { get; set; }
}
但是,当我删除该AutoIncrement
属性时,第二次database.Insert
我得到一个约束类型的 SQLiteException(即使在重置模拟器之后)。
但是,https: //www.sqlite.org/autoinc.html 上的 SQLite 文档强调,出于性能原因,AutoIncrement
应尽可能避免使用。文档建议AutoIncrement
可以避免使用rowId
. 有没有办法rowID
在 SQLite.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 代码中暴露了一个错误,它在没有 时测试 arowId
为 0,AutoIncrement
但该错误与此问题无关。