Как получить автоинкрементный идентификатор в ServiceStack OrmLite?
Для таблицы с идентификатором:
[AutoIncrement]
public int Id { get; set;}
При вставке новой строки в базу данных, каков наилучший способ получить идентификатор объекта?
Например:
db.Insert < > (новый пользователь());
Значение Id равно 0 после вставки, но в базе данных это, очевидно, не так. Единственная возможность, которую я вижу, следующая:
Id = (int)db.GetLastInsertId();
Однако я не считаю, что это будет безопасный звонок. Если есть 100 вставок, происходящих одновременно, может быть возвращен идентификатор для другой вставки. В EF, когда вы делаете вставку, для вас настроен идентификатор.
Кто-нибудь знает, как лучше всего это сделать?
Ответы
Ответ 1
В ServiceStack.OrmLite v4, который по умолчанию использует параметризованные запросы, в db.Save()
есть несколько параметров, которые автоматически заполняют идентификатор AutoIncrement, например:
db.Save(item);
item.Id //populated with the auto-incremented id
В противном случае вы можете выбрать последний идентификатор вставки, используя:
var itemId = db.Insert(item, selectIdentity:true);
Ниже приведены примеры, демонстрирующие новый API API OrmLite.
Для OrmLite v3
Правильный вызов db.GetLastInsertId()
, который для SQL Server под капотом, например, вызывает SELECT SCOPE_IDENTITY(), который возвращает последний вставленный id для что соединение.
Это безопасно, потому что все другие параллельные вставки, которые могут произойти, используют разные соединения БД. Для того, чтобы кто-либо другой использовал одно и то же соединение, его нужно утилизировать и отпустить обратно в пул.
Ответ 2
Вы должны определенно использовать шаблон "Единица работы", особенно в этих сценариях, вы переносите связанные с db коды в области транзакций.
В ormLite вы можете реализовать это через IDbCommand и IDbTransaction (см. пример здесь http://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.OrmLite/ServiceStack.OrmLite.Tests/ShippersExample.cs)
Взглянув на код, вы заметите, что это будет менее волшебное и более ручное кодирование, но это в одну сторону.
Ответ 3
Обновление. Как показано здесь, если вы используете ServiceStack/ORMLite v4, вам нужно использовать параметризованный запрос, чтобы получить вставленный идентификатор. Например:
var UserId = db.Insert<User>(new User(), selectIdentity: true);