13

我从这里(https://github.com/oysteinkrog/SQLite.Net-PCL)使用 PCL 版本的 sqlite.net。

这是我的简单课程。

    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,但这似乎也不起作用。

有没有人有这个工作的例子?

4

6 回答 6

29

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

public class LogEntry
    {
      [PrimaryKey, AutoIncrement]
      public int? Key { get; set;}
      public DateTime Date { get; set; }
    }
于 2015-02-24T19:35:06.257 回答
10

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

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;

我刚刚在上面尝试过,它按预期工作

于 2014-08-27T10:32:55.767 回答
5

这种工作方式是造成很多混乱的根源,但是在设置Insert时将归零的主键视为特殊情况AutoIncrementInsertOrReplace但不会。

所以:

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

如果您InsertOrReplace将一系列零 id 记录放入一个新表中,则第一个将存储在id: 0,随后的每个记录将保存在它之上。而如果您只是Insert每个人,那么因为AutoIncrement第一个将保存在id: 1,而下一个将保存在id: 2等。如您所料。

如果您将键类型更改为可为空的 int,则具有空 id 的记录将被视为插入InsertOrReplace,并且在这种情况下您实际上根本不需要该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,第二个将在尝试插入另一个此类时抛出约束异常。

于 2016-04-05T14:50:34.140 回答
2

为了得到你想要的结果,你需要让你的类的 id 属性可以为空。看这里 链接

于 2018-07-14T08:57:27.763 回答
0

我的解决方案类似于 Joacar 的解决方案,但不是进行更新,而是选择项目,如果它为空,我创建一个新项目,否则更新项目值,然后调用 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);
}

它可能不是最佳的,但它对我有用。

于 2014-10-27T17:46:27.853 回答
0

不需要插入或替换。

只需等待 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;
    }
于 2021-11-05T10:35:18.197 回答