2012-02-15 3 views
13

У меня возникла проблема с отправкой SQL-запроса через DbContext с помощью context.Database.ExecuteSqlCommand().SqlException: Ошибка синтаксиса рядом с 'GO'

Я пытаюсь выполнить

CREATE TABLE Phones([Id] [uniqueidentifier] NOT NULL PRIMARY KEY, 
    [Number] [int],[PhoneTypeId] [int]) 
GO 
ALTER TABLE [dbo].[Phones] ADD CONSTRAINT [DF_Phones_Id] 
    DEFAULT (newid()) FOR [Id] 
GO 

Это не может со строкой ошибки

Incorrect syntax near the keyword 'ALTER'. 
Incorrect syntax near 'GO'. 

Однако работает, что точное утверждение в SSMS работает без ошибок? Любые проблемы, которые мне нужно решить относительно ограничения по умолчанию через DbContext. Я вижу проблемы с людьми, использующими ограничения, и не имея значение IsDbGenerated для true. Я не уверен, как это применимо здесь.

ответ

27

GO не является частью SQL, поэтому его нельзя выполнить с помощью ExecuteSqlCommand(). Подумайте о GO как способе разделения партий при использовании Management Studio или инструментов командной строки. Вместо этого просто удалите инструкции GO, и все будет в порядке. Если вы столкнулись с ошибками, потому что вам нужно запускать свои команды отдельными партиями, просто вызовите ExecuteSqlCommand() один раз для каждой партии, которую вы хотите запустить.

4

Дэйв Маркл избил меня. Фактически, вы можете изменить «GO» на any other string для разделения партий.

Альтернативная реализация здесь заключается в использовании SMO ​​вместо Entity Framework. Существует полезный метод, который называется ExecuteNonQuery, который, я думаю, сделает вашу жизнь намного проще. Here - хороший пример реализации.

+0

То есть true для SSMS, однако, даже если вы измените разделитель партий в SSMS, приведенный выше код по-прежнему будет подавлять «GO». –

+0

Одна заметка, которую я хочу добавить. Если, как и я, вам часто требуется какое-то возвращаемое значение из ваших запросов, которые вы передаете через SMO, имейте в виду, что ExecuteWithResults возвратит исключения, когда они будут запущены в операторы GO и ALTER. Я узнал об этом несколько лет назад и в итоге просто добавил вариант ExecuteNonQuery в наш интерфейс, который проверяется во время выполнения скрипта. – CodeWarrior

0

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

  var text = System.IO.File.ReadAllText("initialization.sql"); 
      var parts = text.Split(new string[] { "GO" }, System.StringSplitOptions.None); 
      foreach (var part in parts) { context.Database.ExecuteSqlCommand(part); } 

      context.SaveChanges(); 

В этом случае ваши команды будут разбиты и выполнены без проблем

Смежные вопросы