Получение последнего идентификатора вставки с SQLite.NET в С#

У меня есть простая проблема с не очень простым решением... В настоящее время я вставляю некоторые данные в базу данных следующим образом:

                kompenzacijeDataSet.KompenzacijeRow kompenzacija = kompenzacijeDataSet.Kompenzacije.NewKompenzacijeRow();
                kompenzacija.Datum = DateTime.Now;
                kompenzacija.PodjetjeID = stranka.id;
                kompenzacija.Znesek = Decimal.Parse(tbZnesek.Text);

                kompenzacijeDataSet.Kompenzacije.Rows.Add(kompenzacija);

                kompenzacijeDataSetTableAdapters.KompenzacijeTableAdapter kompTA = new kompenzacijeDataSetTableAdapters.KompenzacijeTableAdapter();
                kompTA.Update(this.kompenzacijeDataSet.Kompenzacije);

                this.currentKompenzacijaID = LastInsertID(kompTA.Connection);

Последняя строка важна. Почему я подключаю соединение? Ну есть функция SQLite, называемая last_insert_rowid(), которую вы можете вызвать и получить последний идентификатор вставки. Проблема заключается в привязке к соединению, и .NET, похоже, снова открывает и закрывает соединения для каждой операции набора данных. Я думал, что получение соединения из адаптера стола изменит ситуацию. Но это не так.

Кто-нибудь знает, как это решить? Может быть, где получить постоянную связь? Или, может быть, что-то более элегантное?

Спасибо.

ИЗМЕНИТЬ:

Это также проблема с транзакциями, мне понадобится одно и то же соединение, если я захочу использовать транзакции, так что это тоже проблема...

Ответы

Ответ 1

select last_insert_rowid();

И вам нужно будет выполнить его как скалярный запрос.

string sql = @"select last_insert_rowid()";
long lastId = (long)command.ExecuteScalar(sql); // Need to type-cast since `ExecuteScalar` returns an object.

Ответ 2

Используя С# (.net 4.0) с SQLite, класс SQLiteConnection имеет свойство LastInsertRowId, которое равно первому целочисленному ключу самого последнего вставленного (или обновленного) элемента.

Идентификатор rowID возвращается, если в таблице нет первичного целочисленного ключа (в этом случае rowID - это столбец автоматически создается).

Подробнее см. https://www.sqlite.org/c3ref/last_insert_rowid.html.

Что касается обертывания нескольких команд в одной транзакции, любые команды, введенные после начала транзакции и до того, как они будут совершены, являются частью одной транзакции.

long rowID;
using (SQLiteConnection con = new SQLiteConnection([datasource])
{
    SQLiteTransaction transaction = null;
    transaction = con.BeginTransaction();

    ... [execute insert statement]

    rowID = con.LastInsertRowId;

    transaction.Commit()
}

Ответ 3

last_insert_rowid() является частью решения. Он возвращает номер строки, а не фактический идентификатор.

cmd = CNN.CreateCommand();
cmd.CommandText = "SELECT last_insert_rowid()";
object i = cmd.ExecuteScalar();

cmd.CommandText = "SELECT " + ID_Name + " FROM " + TableName + " WHERE rowid=" + i.ToString();
i = cmd.ExecuteScalar();

Ответ 4

Объект SQLiteConnection имеет свойство для этого, поэтому нет необходимости в дополнительном запросе. После INSERT вы просто используете свойство LastInsertRowId вашего объекта SQLiteConnection, которое использовалось для команды INSERT. Тип свойства LastInsertRowId Int64. По умолчанию, как вы уже сейчас, для автоматического приращения для работы первичный ключ в таблице должен быть установлен как AUTOINCREMENT, что является другим темой.

Ответ 5

    database = new SQLiteConnection(databasePath);

    public int GetLastInsertId()
    {
        return (int)SQLite3.LastInsertRowid(database.Handle);
    }