2012-02-15 11 views
13

Mam problem z wysłaniem instrukcji SQL za pomocą DbContext przy użyciu context.Database.ExecuteSqlCommand().Wyjątek wyjątku SqlException: błąd składni w pobliżu "GO"

Próbuję wykonać

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 

ten nie powiedzie się z łańcucha błędów

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

jednak uruchomiony że dokładny rachunek w SSMS przebiega bez błędów? Wszelkie problemy, które muszę rozwiązać, dotyczące domyślnego ograniczenia poprzez DbContext. Widzę problemy z osobami używającymi ograniczeń i nieposiadanie ustawionego zestawu IsDbGener. Nie jestem pewien, jak by to tutaj miało zastosowanie.

Odpowiedz

27

GO nie jest częścią SQL, więc to nie może być wykonany z ExecuteSqlCommand(). Pomyśl o GO jako sposobie oddzielania partii podczas używania Management Studio lub narzędzi wiersza polecenia. Zamiast tego po prostu usuń instrukcje GO i powinno być dobrze. Jeśli napotkasz błędy, ponieważ musisz uruchomić komendy w oddzielnych partiach, po prostu wywołaj ExecuteSqlCommand() raz dla każdej partii, którą chcesz uruchomić.

4

Dave Markle pobił mnie do tego. W rzeczywistości możesz zmienić "GO" na any other string, aby oddzielić partie.

Alternatywną implementacją jest użycie SMO zamiast Entity Framework. Istnieje przydatna metoda o nazwie ExecuteNonQuery, która moim zdaniem znacznie uprości Twoje życie. Here jest dobrym przykładem realizacji.

+0

To prawda dla SSMS, jednak nawet jeśli zmienisz separator wsadowy w SSMS, powyższy kod nadal będzie dławił się na "GO". –

+0

Jedna uwaga, którą chcę dodać. Jeśli lubisz mnie, często potrzebujesz jakiejś wartości zwracanej z zapytań, które przechodzisz przez SMO, pamiętaj, że ExecuteWithResults zwróci wyjątki, gdy uruchomi instrukcje GO i ALTER. Zauważyłem to niedawno i skończyło się po prostu umieszczeniem opcji ExecuteNonQuery w naszym interfejsie użytkownika, który jest sprawdzany w czasie wykonywania skryptu. – CodeWarrior

0

wiem, necroposting jest złe maner, ale może być ten post by uratować czyjeś czasu. Jak wspomniano w poście Dave'a, GO nie jest częścią SQL, dzięki czemu możemy stworzyć mały obejście, aby to działało

  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(); 

W tym przypadku Twoje polecenia będzie podzielony i wykonany bez problemów

Powiązane problemy