Почему у меня не работает SET IDENTITY_INSERT OFF в EF 4.1? - PullRequest
7 голосов
/ 10 октября 2011

Я использую Entity Framework 4.1 Code First, и у меня есть таблица с ключом IDENTITY, потому что все новые записи в этой таблице должны иметь автоматически сгенерированный идентификатор (столбец идентификаторов называется AccountNumber).Мне нужно импортировать некоторые данные из предыдущего воплощения этой системы - эти номера счетов должны быть сохранены.

В предыдущий вопрос , я узнал, что мне нужно УСТАНОВИТЬ IDENTITY_INSERT ON, чтобысохранить старые номера счетов.Идея заключается в том, что при импорте старых клиентов я собираюсь включить IDENTITY_INSERT, запустить необработанный оператор вставки SQL, затем отключить его и продолжить работу с использованием EF-сущностей.

Итак, у меня есть следующий код:

    public const string InsertQuery = "INSERT INTO dbo.Businesses (AccountNumber, Name, Active, CreatedBy, CreatedOn, ModifiedBy, ModifiedOn) VALUES({0}, {1}, {2}, {3}, {4}, {5}, {6})";

...

            dbContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Businesses ON");
            dbContext.Database.ExecuteSqlCommand(InsertQuery, customerData.AccountNumber, customerData.Name, customerData.Active,
                                                 m_userContextManager.GetCurrentUserName(), Now,
                                                 m_userContextManager.GetCurrentUserName(), Now);
            dbContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Businesses OFF");

            // load the entity and map the rest of the attributes
            dbContext.SaveChanges();

Когда я приступаю к выполнению второго оператора, я получаю следующую бешеную ошибку (потому что я просто установил ее на OFF или так я думаю):

Cannot insert explicit value for identity column in table 'Businesses' when IDENTITY_INSERT is set to OFF.

Возвращаемое значение из оператора равно -1, но, поскольку документация по MSDN для ExecuteSqlCommand действительно неадекватна, я понятия не имею, чтоэто означает.Я ожидаю, что будет сгенерировано исключение, если по какой-либо причине утверждение не выполнено.Кто-нибудь знает, что здесь происходит?

Ответы [ 2 ]

11 голосов
/ 16 апреля 2012

Нет необходимости использовать старый добрый ADO.NET;хитрость заключается в объединении всего в одну команду:

public const string InsertQuery = @"
    SET IDENTITY_INSERT dbo.Businesses ON;
    INSERT INTO dbo.Businesses (AccountNumber, Name, Active, CreatedBy, CreatedOn, ModifiedBy, ModifiedOn) VALUES({0}, {1}, {2}, {3}, {4}, {5}, {6});
    SET IDENTITY_INSERT dbo.Businesses OFF;
";

dbContext.Database.ExecuteSqlCommand(InsertQuery, customerData.AccountNumber, customerData.Name, customerData.Active,
                                     m_userContextManager.GetCurrentUserName(), Now,
                                     m_userContextManager.GetCurrentUserName(), Now);

// load the entity and map the rest of the attributes
dbContext.SaveChanges();

Кроме того, вы можете отбросить SET IDENTITY_INSERT dbo.Businesses OFF (так как IDENTITY_INSERT в любом случае выключен в конце команды) и dbContext.SaveChanges(), поскольку ExecuteSqlCommand выполняетсякоманда немедленно;он не ждет SaveChanges ().

5 голосов
/ 10 октября 2011

ExecuteSqlCommand откроет соединение, выполнит sql и затем закроет его. Поэтому ваша следующая команда будет выполняться с использованием другого соединения.

Что вы можете сделать, это использовать простые старые классы ADO.net, чтобы вставить данные в одну транзакцию. Или запишите данные и выполните их как , показанное здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...