Entity Framework 4.2, Невозможно установить Identity Insert ON

Я хотел бы добавить записи в массив в таблицу с заданным идентификатором, чтобы я мог построить иерархию для отображения записей в режиме древовидной структуры. Я могу отдельно добавлять записи, которые отлично работают, и я не устанавливаю ID. Я хотел бы установить идентификаторы только навалом, поэтому я устанавливаю DatabaseGenerated Option как None в столбце id для моего объекта как None.

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{

     foreach (ErrorCode ec in errorCodesStep3.errorcodesUsers)
     {

           errorCode.ID = ec.ID;
           errorCode.ParentID = ec.ParentID;
           errorCode.ErrorDescription = ec.ErrorDescription;
           db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ErrorCode ON");
           db.ErrorCode.Add(errorCode);
           db.SaveChanges();    
           scope.Complete();
     }
}

ErrorCode

[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }

Я получаю сообщение об ошибке:

не может установить идентификатор, когда вставка идентификатора выключена.

Не уверен, что случилось, так как я видел примеры того, что вставка идентификатора может быть включена. Я использую EF Version 4.2.0.0 и Runtime Version v4.0.30319. Я могу легко добавить инструкцию INSERT через executeSQL с параметризованными переменными, но я хотел бы сделать это с помощью сущности framework. Похоже, что db.Database.ExecuteSqlCommand находится в отдельной области действия и закрывается сразу и недоступен, когда выполняется db.savechanged.

Ответ 1

Попробуйте следующее: Entity Framework с вставкой Identity

Возможно так:

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
    using (var db = new Context()) // your Context
    {
        db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ErrorCode ON");
        ErrorCode errorCode = db.ErrorCode.First(); // for example
        foreach (ErrorCode ec in errorCodesStep3.errorcodesUsers)
        {
            errorCode.ID = ec.ID;
            errorCode.ParentID = ec.ParentID;
            errorCode.ErrorDescription = ec.ErrorDescription;    
            db.ErrorCode.Add(errorCode);
        }
        db.SaveChanges();
        db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ErrorCode OFF");
        scope.Complete();
    }
}

Ответ 2

У меня возникла та же проблема: у нас была таблица, в которой была установлена ​​личность. то нам нужно было переключить идентификатор на false (я имею в виду сделать это следующим образом)

[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }

но это не сработало после миграции и обновления базы данных. после того, как я столкнулся с проблемой, я основал эту статью что означает, что идентификация включения/выключения включения не является прямой, и теперь она не поддерживается платформой Entity Framework.

поэтому решение (которое работало для меня) было следующим

в Visual Studio откройте таблицу в представлении конструктора и выберите столбец, представляющий первичный ключ (который в вашем случае "ID" ), затем из панели свойств найдите свойство "Спецификация идентификатора" (он должен иметь значение true) устанавливает значение false, и не забудьте обновить таблицу, нажав кнопку "Обновить", чтобы выполнить оператор SQL в таблице. (кнопка обновления существует на панели инструментов таблицы)

затем попробуйте запустить код, он должен работать.

Я надеюсь, что это будет полезно. если у вас есть какие-либо вопросы, пожалуйста, дайте мне знать.

Ответ 3

Вот код, который я проверил, делает то, что вы хотите. Идея состоит в том, чтобы использовать одно соединение как для ExecuteSqlCommand, так и для операций вставки, и кажется, что вызов BeginTransaction() делает трюк:

using (var db = new TestEntities()) { 
    using (var tran = db.Database.BeginTransaction()) {
       db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Error ON");
            foreach (var id in Enumerable.Range(1, 20)) {
                var ec = new Error();
                ec.ErrorID = id;
                db.Errors.Add(ec);
            }
            db.SaveChanges();
            db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Error OFF");
            tran.Commit();
        }
    }
}

Ответ 4

Добавьте другой столбец для управления иерархией. Столбец идентификатора не должен использоваться для этой цели.

Извините, что не ответил на вопрос, но я не думаю, что ваше решение правильно.