xamarin 如何在www.example.com PCL中使用InsertOrReplacesqlite.net?

vktxenjb  于 2023-04-18  发布在  SQLite
关注(0)|答案(6)|浏览(121)

我在这里使用的是www.example.com的PCL版本sqlite.net(https://github.com/oysteinkrog/SQLite.Net-PCL)。
这是我的简单类。

public class LogEntry
    {
      [PrimaryKey, AutoIncrement]
      public int Key { get; set;}
      public DateTime Date { get; set; }
    }

当创建一个新的LogEntry示例时,Key会自动设置为0。我将Date设置为某个值,然后调用InsertOrReplace。该记录确实保存在我的数据库中。Key字段获得自动增量值,该值恰好为0,因为它是第一条记录。
然后我创建一个新的LogEntry示例(Key自动初始化为0)并将日期设置为其他值。然后我调用InsertOrReplace。由于存在一个Key为0的现有记录,因此该记录将被更新。
什么是正确的方法来处理这个问题?我考虑初始化的关键-1,但似乎也没有工作。
有没有人有一个这样的工作的例子?

y3bcpkx1

y3bcpkx11#

我遇到了与您描述的相同的问题。尝试

var rowsAffected = Connection.Update(object);

if(rowsAffected == 0) {
    // The item does not exists in the database so lets insert it
    rowsAffected = Connection.Insert(object);
}

var success = rowsAffected > 0;

return success;

我只是尝试了上面和它的工作预期

nr7wwzry

nr7wwzry2#

这种工作方式是许多混乱的根源,但是当AutoIncrement被设置时,Insert将零主键视为特殊情况,而InsertOrReplace则没有。
因此:

[PrimaryKey, AutoIncrement]
public int id { get; set; }

如果你InsertOrReplace一系列的零id记录到一个新的表中,第一个将被存储在id: 0,每个后续的记录将保存在它上面。然而,如果你只是Insert每一个,那么由于AutoIncrement,第一个将保存在id: 1,下一个将保存在id: 2等。
如果你将key类型改为nullable int,那么带有null id的记录将被InsertOrReplace当作insert,在这种情况下,你实际上根本不需要AutoIncrement属性,它们仍然会按照从1开始的顺序保存。

[PrimaryKey]
public int? id { get; set; }

如果你因为某些原因不能使用它,你可以自己检查零个id,并调用Insert,例如。

Func<Foo, int> myInsertOrReplace = x => 
{ 
   return x.id == 0 ? _db.Insert(x) : _db.InsertOrReplace(x); 
};

但在这种情况下,你必须使用AutoIncrement属性,否则第一个零插入将保存在0,第二个将抛出一个约束异常,当它试图插入另一个这样的。

piah890a

piah890a3#

为了得到你想要的结果,你需要让你的类的id属性为空。

egdjgwm8

egdjgwm84#

我的解决方案与Joacar的类似,但不是进行更新,而是选择项目,如果它为null,则创建一个新项目,否则更新该项目的值,然后调用InserOrReplace。

var existingKey = await this.GetItem(key);
Item item;

if (existingKey.Value != null)
{
    profile = new Item
    { 
        Id = existingKey.Id,
        Key = existingKey.Key,
        Value = newValue,
    };

    this.InsertOrReplaceAsync(item);
}
else
{
    item = new Item
    {
        Key = key,
        Value = value, 
    };

    this.InsertAsync(item);
}

它可能不是最佳的,但它为我工作。

42fyovps

42fyovps5#

不需要插入或替换。
只需等待InsertAsync。
保证有效...

if (object.ID != 0)
    {
      // Update an existing object.
      var T = DatabaseAsyncConnection.UpdateAsync(object);
      T.Wait();
      return T;
    }
    else
    {
      // Save a new object.
      var T = DatabaseAsyncConnection.InsertAsync(object);
      T.Wait();
      return T;
    }
dgsult0t

dgsult0t6#

如果你把Key改为一个可空的类型(int?),它应该可以工作。然后SQLite看到null进来,并在需要时生成新的id。

public class LogEntry
    {
      [PrimaryKey, AutoIncrement]
      public int? Key { get; set;}
      public DateTime Date { get; set; }
    }

相关问题