LINQ-to-SQL .ExecuteCommand () не работает с параметризованными именами объектов - PullRequest
4 голосов
/ 07 июля 2011

Я немного сбит с толку этим и надеюсь, что кто-то сможет прояснить, что происходит.

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

context.ExecuteCommand( "ALTER TABLE {0} NOCHECK CONSTRAINT {1}", "MyTable", "FK_MyTable_MyOtherTable" );

К сожалению, этот код бомбит с ошибкой SQL "Неверный синтаксис рядом с '@ p0'."

Когда я запускаю профилировщик, я вижу, что генерируется SQL:

exec sp_executesql 
N'ALTER TABLE @p0 NOCHECK CONSTRAINT @p1',
N'@p0 varchar(4000),@p1 varchar(4000)',
@p0=N'MyTable',
@p1=N'FK_MyTable_MyOtherTable'

Из всего, что я могу найти в SQL Books Online и в документации по LINQ-to-SQL, это должно сработать.

Вместо этого я прибегнул к этому:

context.ExecuteCommand( String.Format( "ALTER TABLE {0} NOCHECK CONSTRAINT {1}", "MyTable", "FK_MyTable_MyOtherTable" ) );

Это работает, но в некотором роде лишает цели возможности передавать параметры в .ExecuteCommand ().

Так это какая-то странность в LINQ-to-SQL, SQL Server или я просто очень запутался?

Любые идеи будут высоко оценены!

Ответы [ 3 ]

7 голосов
/ 07 июля 2011

Как вы узнали - Linq-to-SQL будет довольно агрессивно пытаться параметризовать ваши запросы. Что является хорошей вещью , в большинстве случаев.

Но в случае оператора ALTER TABLE... такие вещи, как имя таблицы и т. Д. не могут быть параметризованы , поэтому он не работает.

Я не знаю, есть ли какой-нибудь способ заставить Linq-to-SQL не параметризовать определенные запросы, которые должны быть выполнены ExecuteCommand - тем временем, я думаю, операторы, которые не вовлекайте манипулирование данными (вставку, обновление и т. д.), а скорее манипулируйте структурой вашей базы данных, лучше всего использовать подход String.Format(...) для получения фактического запроса SQL в виде строки перед вызовом .ExecuteCommand().

1 голос
/ 07 июля 2011

Linq to SQL в основном просто переводит то, что вы ему дали. Проблема в том, что вы не можете иметь имена таблиц в качестве параметров, поэтому следующее не работает.

DECLARE @TableName varchar

SET @Tablename='MyTable'

SELECT * FROM @TableName

Похоже, у вас уже есть решение, и я думаю, что оно хорошее.

1 голос
/ 07 июля 2011

Вы не можете использовать объекты SQL в качестве параметров.

Так что вторая версия - единственная опция.

...