У меня есть таблица сообщений с идентификатором столбцов (первичный ключ, автоинкремент) и содержимым (текст).
У меня есть таблица Users с именем пользователя столбцов (первичный ключ, текст) и Hash.
Сообщение отправляется одним Отправителем (пользователем) нескольким получателям (пользователям), и у получателя (пользователя) может быть много сообщений.
Я создал таблицу Messages_Recipients с двумя столбцами: MessageID (со ссылкой на столбец ID таблицы Messages и Recipient (со ссылкой на столбец имени пользователя в таблице Users). Эта таблица представляет отношение «многие ко многим» между получателями и сообщениями.
Итак, у меня такой вопрос. Идентификатор нового сообщения будет создан после того, как он будет сохранен в базе данных. Но как я могу сохранить ссылку на MessageRow, которую я только что добавил, чтобы получить этот новый MessageID?
Конечно, я всегда могу найти в базе данных последнюю добавленную строку, но это может вернуть другую строку в многопоточной среде?
РЕДАКТИРОВАТЬ: Насколько я понимаю, для SQLite вы можете использовать расширение SELECT last_insert_rowid()
. Но как мне вызвать это утверждение из ADO.Net?
Мой код сохранения состояния (сообщения и получатели сообщений - это таблицы данных):
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);
}
Ответы:
В SQL Server вы должны ВЫБРАТЬ SCOPE_IDENTITY (), чтобы получить последнее значение идентификатора для текущего процесса.
С SQlite похоже, что для автоинкремента вы бы сделали
SELECT last_insert_rowid()
сразу после вставки.
http://www.mail-archive.com/sqlite-users@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(); }
источник
If the table has a column of type INTEGER PRIMARY KEY then that column is another alias for the rowid.
Еще один вариант - посмотреть системную таблицу
sqlite_sequence
. Ваша база данных sqlite будет иметь эту таблицу автоматически, если вы создали любую таблицу с первичным ключом автоинкремента. Эта таблица предназначена для sqlite, чтобы отслеживать поле автоинкремента, чтобы он не повторял первичный ключ даже после удаления некоторых строк или после сбоя какой-либо вставки (подробнее об этом здесь http://www.sqlite.org/autoinc .html ).Таким образом, эта таблица дает дополнительное преимущество: вы можете узнать первичный ключ только что вставленного элемента даже после того, как вы вставили что-то еще (в других таблицах, конечно!). Убедившись, что ваша вставка прошла успешно (иначе вы получите ложное число), вам просто нужно сделать:
select seq from sqlite_sequence where name="table_name"
источник
У меня были проблемы с использованием
SELECT last_insert_rowid()
в многопоточной среде. Если другой поток вставляет в другую таблицу, которая имеет autoinc, last_insert_rowid вернет значение autoinc из новой таблицы.Вот где они заявляют об этом в документе:
Это из sqlite.org doco
источник
Пример кода из решения @polyglot
SQLiteCommand sql_cmd; sql_cmd.CommandText = "select seq from sqlite_sequence where name='myTable'; "; int newId = Convert.ToInt32( sql_cmd.ExecuteScalar( ) );
источник
Согласно Android Sqlite получить последний идентификатор строки вставки, есть еще один запрос:
SELECT rowid from your_table_name order by ROWID DESC limit 1
источник
ORDER BY
. Должно быть быстрее, но я этого не тестировал:SELECT MAX(rowid) FROM your_table_name