【发布时间】:2014-10-31 21:48:58
【问题描述】:
这似乎是我遗漏了一个简单的细节,我就是不知道是什么。
有这个
string deleteTrigger =
"IF OBJECT_ID('@p0') IS NOT NULL " +
"DROP TRIGGER [@p1] ";
string createTrigger =
"CREATE TRIGGER [@p0] " +
"ON [dbo].[@p1] " +
"AFTER DELETE AS " +
"BEGIN " +
"SET NoCount ON " +
"DELETE FROM [dbo].[MyTable] WHERE ID IN (SELECT ID FROM DELETED) " +
"END ";
object[] parameterList = new object[] {"Tr_SomeTable_AD", "Tr_SomeTable_AD" };
context.Database.ExecuteSqlCommand(deleteTrigger,parameterList); // Works
parameterList = new object[] { "Tr_SomeTable_AD", "SomeTable" };
context.Database.ExecuteSqlCommand(createTrigger, parameterList); // Exception thrown here!
在我的InitializeDatabase(DbContext) 中抛出异常:
SqlException:单词“TRIGGER”附近的语法不正确
在第二个ExecuteSqlCommand(第一个工作正常)。我也试过了
context.Database.ExecuteSqlCommand(createTrigger, "Tr_SomeTable_AD", "SomeTable");
而不是使用object[],但结果是一样的。
我看到this question,但答案并没有解决我的问题。我知道问题一定与我使用参数有关,因为如果我只是将值放在 createTrigger 字符串中,SQL 命令就可以工作。但是,我希望将其参数化,以便更轻松地在不同的表上使用相同的触发器创建代码。
解决方案:
正如@marc_s 所说(请参阅下面的答案),我无法在 T-SQL 中参数化表或列(或触发器)名称 - 我必须在 C# 中创建完整的最终 T-SQL 语句(使用 string.格式())。因此:
string deleteTrigger = "..."; // same as before
string createTrigger =
"CREATE TRIGGER [dbo].[{0}] " +
"ON [dbo].[{1}] " + ...
object[] parameterList = new object[] {"Tr_SomeTable_AD", "Tr_SomeTable_AD" };
context.Database.ExecuteSqlCommand(string.Format(deleteTrigger,parameterList));
parameterList = new object[] { "Tr_SomeTable_AD", "SomeTable" }; // Use string.Format() here!
context.Database.ExecuteSqlCommand(string.Format(createTrigger, parameterList));
成功了。
【问题讨论】:
-
您不能在 T-SQL 中参数化表或列(或触发器)名称 - 您必须在 C# 中创建完整的最终 T-SQL 语句(使用 @ 987654328@) 然后执行完成的 T-SQL 语句
-
您可以使用格式化字符串的方法,因为在当前情况下参数使用不正确。
-
@marc_s 是的:就是这样。随意写下这个答案,我会接受。谢谢。
标签: c# entity-framework triggers dbcontext