В SQL 2005 и выше существует трюк для решения этой проблемы без изменения страниц данных таблицы. Это важно для больших таблиц, где касание каждой страницы данных может занимать минуты или часы. Трюк также работает, даже если столбец идентификатора является первичным ключом, является частью кластерного или некластеризованного индекса или других ошибок, которые могут отключить более простое решение «добавить / удалить / переименовать столбец».
Вот трюк: вы можете использовать инструкцию SQL Server ALTER TABLE ... SWITCH для изменения схемы таблицы без изменения данных, то есть вы можете заменить таблицу на IDENTITY с идентичной схемой таблицы, но без столбца IDENTITY. Тот же трюк работает, чтобы добавить IDENTITY в существующий столбец.
Обычно ALTER TABLE ... SWITCH используется для эффективной замены полного раздела в многораздельной таблице новым, пустой раздел. Но он также может использоваться и в несегментированных таблицах.
Я использовал этот трюк, чтобы преобразовать менее чем за 5 секунд столбец таблицы из 2,5 миллиардов строк из IDENTITY в не- IDENTITY (для запуска многочасового запроса, чей план запроса работал лучше для столбцов без идентификатора), а затем восстановил параметр IDENTITY, снова менее чем за 5 секунд.
Вот пример кода того, как оно работает.
CREATE TABLE Test
(
id int identity(1,1),
somecolumn varchar(10)
);
INSERT INTO Test VALUES ('Hello');
INSERT INTO Test VALUES ('World');
-- copy the table. use same schema, but no identity
CREATE TABLE Test2
(
id int NOT NULL,
somecolumn varchar(10)
);
ALTER TABLE Test SWITCH TO Test2;
-- drop the original (now empty) table
DROP TABLE Test;
-- rename new table to old table's name
EXEC sp_rename 'Test2','Test';
-- update the identity seed
DBCC CHECKIDENT('Test');
-- see same records
SELECT * FROM Test;
Это, очевидно, более активное участие, чем решения в других ответах, но если ваша таблица большая, это может быть реальной спасающей жизнью. Есть некоторые оговорки:
В TechNet есть хорошая статья , в которой подробно описаны требования выше. UPDATE -
Здесь есть еще одна оговорка, о которой стоит упомянуть. Несмотря на то, что новая таблица с радостью получит данные из старой таблицы, а все новые строки будут вставлены после шаблона идентификации, они будут начинаться с 1 и потенциально прерываться, если указанный столбец является первичным ключом. Рассмотрите возможность запуска
DBCC CHECKIDENT('
сразу после переключения. См. msdn.microsoft.com/en-us/library/ms176057.aspx для получения дополнительной информации.') Если таблица активно расширяется новыми строками (что означает у вас мало времени, если есть время простоя между добавлением IDENTITY и добавлением новых строк, вместо
DBCC CHECKIDENT
вы захотите вручную установить начальное значение идентификатора в новой схеме таблицы больше, чем самый большой существующий идентификатор в таблице , напримерIDENTITY (2435457, 1)
. Возможно, вы сможете включить в транзакциюALTER TABLE...SWITCH
иDBCC CHECKIDENT
(или нет - не проверили это), но похоже, что установка начального значения вручную будет проще и безопаснее.Очевидно, что если новые строки не добавляются в таблицу (или они добавляются только иногда, как ежедневный процесс ETL), то этого состояния гонки не произойдет, так что
DBCC CHECKIDENT
в порядке.
У вас нет DbSet<string>
(и вы не можете иметь), поэтому строка не является объектом базы данных. Сначала вам нужно найти UserProfile
сущность:
var userProfile = context.UserProfiles.FirstOrDefault(u => u.UserName == userName);
... а затем удалить это:
context.UserProfiles.Remove(userProfile);