В настоящее время я пытаюсь внести некоторые локальные данные в базу данных, работая с зеркалами EF Code-First. Эти данные уже имеют уникальный идентификатор, поэтому изначально первый «набор» данных должен быть вставлен как есть.
Теперь я подумываю установить «DatabaseGeneratedOption.None»,
добавьте набор данных в базу данных, вычислите последний использованный идентификатор, выполните повторное заполнение с помощью команды T-SQL 'dbcc checkident (tablename, reseed, [NEW AUTO ID])'
а затем добавьте еще одну миграцию, сбросив GeneratedOption в DatabaseGeneratedOption.Identity.
Это правильный подход и / или даже возможен ли я или я не на том пути?
Любые выводы будут оценены
С наилучшими пожеланиями
РЕДАКТИРОВАТЬ - Михалс ответ
Пытался реализовать ответ Михалса, но идентификаторы все еще «генерируются» базой данных, а мои явные значения игнорируются. Может быть, это способ, которым я вставляю значения:
MyDbContext context = // GetContext;
DbSet<SomeClass> dbSet = context.SomeClass;
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT " + someClassTableName + " ON");
foreach(SomeClass sc in toAdd)
{
// sc already contains all data including its unique ID
sbSet.Add(sc);
}
context.SaveChanges();
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT " + someClassTableName + " OFF");
Решение / w Михалса ответы
Ну,
Я изо всех сил старался реализовать ответ Михалса различными способами и, наконец, пришел к (действительно странному) решению.
Во-первых, у меня есть мой класс DBContext и, следовательно, класс Dervied с именем DBContextEditor. То, что это делает, - ничто иное, как переопределение OnModelCreating, где я изменяю все свойства «Идентичность».
public class MyContextEditor : MyContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<SomeClass>()
.Property(e => e.ID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}
}
Использование этого класса в сочетании с некоторыми другими приемами из других постов (см. Источники ниже), наконец, дало мне результат, который я искал.
Наконец-то у меня было что-то вроде этого:
MyContext context = new MyContextEditor();
DbSet<SomeClass> dataSet = context.SomeClass;
// this.Clear(dataSet); Just for testing to reset Identity Auto ID and remove all Data
// this.Reset(dataSet);
context.Database.Connection.Open();
// Add data to dataSet...
// dataSet.Add(toAdd);
// Apply Michals answer and save
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT " + tableName + " ON");
context.SaveChanges();
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT " + tableName + " OFF");
// Close Connection
context.Database.Connection.Close();
Я также попытался реализовать переопределение в классе MyContext, который завершился ошибкой, в которой говорилось: «Модель выпечки отличается ...», что также изменило свойство ID на «идентичность».
Наконец, этот подход дал мне желаемый контроль над добавлением Идентификационных данных, сохраняя при этом возможность генерировать значения идентификаторов. Кроме того, любая дальнейшая миграция не меняет модель и не удаляет флаг «Идентичность», тогда как [DatabaseGeneratedOption] его удалял.
Также возможно и рекомендуется хранить это в таком виде:
using( var transaction = context.Database.BeginTransaction'))
Только для справки Модель в псевдокоде
class SomeClass
{
[Key]
public int ID { get; set; }
public string Title { get; set; }
// More Properties
}
Похожие сообщения и источники