How this works is a source of great confusion, but while Insert treats zero primary keys as a special case when AutoIncrement set, InsertOrReplace not.
So using
[PrimaryKey, AutoIncrement] public int id { get; set; }
if you InsertOrReplace series of null id records in a new table, the first will be stored in id: 0 , and each subsequent one will save it. If you just Insert each of them, then because of AutoIncrement first one will save in id: 1 and the next one in id: 2 , etc., As you might expect.
If you change the key type to nullable int, then records with null identifiers will be treated as InsertOrReplace inserts, in which case you do not need the AutoIncrement attribute at AutoIncrement , they will still remain in the sequence starting from 1.
[PrimaryKey] public int? id { get; set; }
If you cannot use this for any reason, you can do your own checking for null identifiers and for those who call Insert instead, for example.
Func<Foo, int> myInsertOrReplace = x => { return x.id == 0 ? _db.Insert(x) : _db.InsertOrReplace(x); };
but in this case you should use the AutoIncrement attribute, otherwise the first zero insert will be stored at 0, and the second will throw a constraint exception when it tries to insert another such.
stovroz
source share