Как получить последний автоувеличенный идентификатор от таблицы SQLite?

У меня есть таблица сообщения со столбцами ID (первичный ключ, автоинкремент) и Содержание (текст).
У меня есть таблица Users с именем пользователя столбцов (первичный ключ, текст) и Хеш.
Сообщение отправляется одним Отправителем (пользователь) многим получателям (пользователь), и у получателя (пользователь) может быть много сообщений.
Я создал таблицу Messages_Recipients с двумя столбцами: MessageID (обращающийся к столбцу ID таблицы сообщений и Получателя (обращающийся к столбцу имени пользователя в таблице Users). Эта таблица представляет многих многим отношение между получателями и сообщениями.

Так, вопрос, который я имею, является этим. Идентификатор нового сообщения будет создан после того, как он будет сохранен в базе данных. Но как я могу держать ссылку на MessageRow, который я просто добавил для получения этого нового MessageID?
Я могу всегда искать базу данных последнюю строку, добавленную, конечно, но это могло возможно возвратить другую строку в многопоточной среде?

Править: Насколько я понимаю для SQLite можно использовать SELECT last_insert_rowid(). Но как я называю этот оператор от ADO.NET?

Мой код Персистентности (сообщениями и messagesRecipients является DataTables):

public void Persist(Message message)
{
    pm_databaseDataSet.MessagesRow messagerow;
    messagerow=messages.AddMessagesRow(message.Sender,
                            message.TimeSent.ToFileTime(),
                            message.Content,
                            message.TimeCreated.ToFileTime());
    UpdateMessages();
    var x = messagerow;//I hoped the messagerow would hold a
    //reference to the new row in the Messages table, but it does not.
    foreach (var recipient in message.Recipients)
    {
        var row = messagesRecipients.NewMessages_RecipientsRow();
        row.Recipient = recipient;
        //row.MessageID= How do I find this??
        messagesRecipients.AddMessages_RecipientsRow(row);
        UpdateMessagesRecipients();//method not shown
    } 

}

private void UpdateMessages()
{
    messagesAdapter.Update(messages);
    messagesAdapter.Fill(messages);
}
72
задан O'Neil 28 August 2018 в 22:02
поделиться

3 ответа

С помощью SQL Server вы должны SELECT SCOPE_IDENTITY() получить последнее идентификационное значение для текущего процесса.

С SQlite это выглядит так, как будто для автоинкремента вы бы сделали

SELECT last_insert_rowid()

сразу после вставки.

_COPY2@sqlite.org/msg09429.html

В ответ на ваш комментарий для получения этого значения вы захотите использовать SQL или OleDb код типа:

using (SqlConnection conn = new SqlConnection(connString))
{
    string sql = "SELECT last_insert_rowid()";
    SqlCommand cmd = new SqlCommand(sql, conn);
    conn.Open();
    int lastID = (Int32) cmd.ExecuteScalar();
}
75
ответ дан 24 November 2019 в 12:31
поделиться

У меня были проблемы с использованием выберите Last_insert_rowid () в многопоточной среде. Если еще один поток вставляет в другую таблицу, которая имеет AUTOINC, Last_insert_Rowid вернет значение AUTOINC из новой таблицы.

Вот где они утверждают, что в DOCO:

Если отдельная нить выполняет новую вставку в одном и том же подключении к базе данных, когда функция SQLite3_Last_insert_rowid () работает и, таким образом, изменяет последнюю rowid вставку, то значение, возвращенное sqlite3_last_insert_rowid () непредсказуемо и не будет равна либо старой, либо новой последней вставке ROWID.

Это из SQLite.org Doco

8
ответ дан 24 November 2019 в 12:31
поделиться

Еще один вариант - просмотреть системную таблицу sqlite_sequence . Ваша база данных sqlite будет иметь эту таблицу автоматически, если вы создали любую таблицу с первичным ключом автоинкремента. Эта таблица предназначена для sqlite, чтобы отслеживать поле автоинкремента, чтобы он не повторял первичный ключ даже после удаления некоторых строк или после сбоя какой-либо вставки (подробнее об этом здесь http: //www.sqlite. org / autoinc.html ).

Таким образом, эта таблица дает дополнительное преимущество, заключающееся в том, что вы можете узнать первичный ключ только что вставленного элемента даже после того, как вы вставили что-то еще (в других таблицах, конечно!). Убедившись, что вставка прошла успешно (иначе вы получите ложное число), вам просто нужно сделать:

select seq from sqlite_sequence where name="table_name"
100
ответ дан 24 November 2019 в 12:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: