2016-11-02 6 views
1

У меня есть простой объект:Xamarin Sqlite Вставка не возвращает последний первичный ключ идентификатора

[Table("History")] 
public class History 
{ 
    [PrimaryKey, AutoIncrement, Column("_id")] 
    public int Id { get; set; } 

    [Indexed(Name = "IDX_History", Order = 1, Unique = true)] 
    public int Prefix { get; set; } 

    [Indexed(Name = "IDX_History", Order = 2, Unique = true)] 
    public int Stem { get; set; } 

    [Indexed(Name = "IDX_History", Order = 3, Unique = true)] 
    public int Suffix { get; set; } 

    [Indexed(Name = "IDX_Favourite")] 
    public bool IsFavourite { get; set; } 

    public DateTime LastViewed { get; set; } = DateTime.Now; 
} 

Я пытаюсь сделать вставку, если ее новым или получить последний вставленный идентификатор, если он уже существует:

public static int SaveSolutionToHistory(Solution sol) 
{ 
    lock (_db) 
    { 
     var existingHistory = _db.Table<History>().FirstOrDefault(h => h.Prefix == sol.Prefix.Id 
      && h.Stem == sol.Stem.Id 
      && h.Suffix == sol.Suffix.Id); 

     if (existingHistory != null) 
     { 
      existingHistory.LastViewed = DateTime.Now; 
      _db.Update(existingHistory); 
      return existingHistory.Id; 
     } 

     _db.Insert(new History 
     { 
      Prefix = sol.Prefix.Id, 
      Stem = sol.Stem.Id, 
      Suffix = sol.Suffix.Id 
     }); 

     return _db.ExecuteScalar<int>("SELECT last_insert_rowid()"); 
    } 
} 

верхняя часть работает отлично в возвращающей идентификатор для существующих записей, но по какой-то причине код вставки всегда возвращает , когда он должен вернуть последний вставленный первичный автоинкрементного идентификатор (как указан в методах XML комментариях):

 _db.Insert(new History 
    { 
     Prefix = sol.Prefix.Id, 
     Stem = sol.Stem.Id, 
     Suffix = sol.Suffix.Id 
    }); 

И это возвращает правильный идентификатор:

return _db.ExecuteScalar<int>("SELECT last_insert_rowid()"); 

Это кажется неэффективным для меня сделать два удара, как это или сделать это в качестве не сильно типизированных. Есть ли причина, почему _db.Insert не возвращает правильный идентификатор?

Я использую VS 2015, с HAXM и Marshmallow x86_64 Google API Image.

ответ

2

У меня была такая же проблема, только что нашел ответ here, полный XML комментарий:

// 
// Summary: 
//  /// Inserts the given object and retrieves its /// auto incremented primary key 
//  if it has one. /// 
// 
// Parameters: 
// obj: 
//  /// The object to insert. /// 
// 
// Returns: 
//  /// The number of rows added to the table. /// 

Что резюме подразумевает под «отыскивает» является то, что он обновляет значение поля PK в объекте который вы передали ему, поэтому, если вы хотите использовать последний вставленный идентификатор, вы можете использовать это

0

Вы можете вставлять строки в базу данных с помощью Insert. Если таблица содержит первичный ключ автоинкрементных, то значение этого ключа будут доступны вам после вставки:

public static void AddStock (SQLiteConnection db, string symbol) { 
    var s = new Stock { Symbol = symbol }; 
    db.Insert (s); 
    Console.WriteLine ("{0} == {1}", s.Symbol, s.Id); 
} 

Это означает, что идентификатор будет доступен в поле Идентификатор объекта.

https://components.xamarin.com/gettingstarted/sqlite-net