2012-02-15 26 views
13

我在使用context.Database.ExecuteSqlCommand()通過DbContext發送SQL語句時遇到問題。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視爲分離批次的一種方式。相反,只是刪除GO語句,你應該沒問題。如果由於需要分批運行命令而遇到錯誤,只需爲每個要運行的批次調用ExecuteSqlCommand()一次。

4

Dave Markle打敗了我。實際上,您可以將「GO」更改爲any other string以分開批次。

這裏的一個替代實現是使用SMO而不是實體框架。有一種有用的方法叫做ExecuteNonQuery,我認爲它會讓你的生活變得更簡單。 Here是一個很好的實現示例。

+0

這是對於SSMS是正確的,但是即使你改變了SSMS中的批處理分隔符,上面的代碼仍然會扼殺「GO」。 – 2012-02-15 05:00:25

+0

我想補充一點。如果像我一樣,通常需要通過SMO傳遞的查詢的某種返回值,請注意,ExecuteWithResults在運行到GO和ALTER語句時將返回異常。前一段時間我發現了這一點,最後只是在我們的用戶界面上提供了一個ExecuteNonQuery選項,並在腳本運行時進行檢查。 – CodeWarrior 2013-05-29 15:01:50

0

我知道,necroposting是不好的,但可能是這篇文章會節省一些人的時間。因爲它是在Dave的文章中提到,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(); 

在這種情況下,您的命令將被分裂,沒有問題執行