背景:
如果我有以下程序
public class Program { public static void Main() { using(var connection = new SqlConnection("Server=(local);Database=Testing;Trusted_Connection=True")) using (var command = connection.CreateCommand()) { connection.Open(); command.CommandText = "UPDATE Foo set Bar = @Text"; command.Parameters.Add("@Text", SqlDbType.VarChar, 50).Value = "Hello World!"; command.ExecuteNonQuery(); } } }
执行后,将运行以下查询(根据SQL Server Profiler)
exec sp_executesql N'UPDATE Foo set Bar = @Text',N'@Text varchar(50)',@Text='Hello World!'
我的问题:
我想做的是,如果我有以下情况
command.CommandText = "UPDATE Foo set Bar = @Text"; command.Parameters.Add("@Text", SqlDbType.VarChar, 50).Value = "Hello World!"; string query = GenerateQuery(command);
GenerateQuery 将返回字符串
GenerateQuery
"exec sp_executesql N'UPDATE Foo set Bar = @Text',N'@Text varchar(50)',@Text='Hello World!'"
我有能力编写一个解析器,该解析器遍历Parameters集合中的每个参数并构建字符串。但是,在我从头开始编写此解析器之前,.NET中是否有某些类或函数已经执行了我所忽略的操作?
Parameters
如果我可以访问编写该解析器的参数的MetaType,将非常容易,但是使用生产应用程序中的反射来访问.NET框架的未发布内部API时,我觉得不值得。
格雷戈里的答案是正确的,但大多数都是错误的。没错,没有public可以调用的方法,但是有private一个(您不能调用)确实可以重新打包CommandText和SqlParameterCollection作为存储过程调用的方法,sp_executesql并以预先格式化的参数名和数据类型列表作为参数。该存储过程的第二个输入参数(请参阅BuildParamList下面的注释)。
public
private
CommandText
SqlParameterCollection
sp_executesql
BuildParamList
虽然这是Microsoft源代码,但该代码也是开放源.NET Core项目的一部分,该项目主要是在MIT许可下发布的。意思是,您可以复制并粘贴所需的部分:-)。即使该代码仅位于referencesource.microsoft.com上,您仍可以从中了解所需信息,并使用它来验证您的版本在功能上与之一致。
似乎您需要的主要是BuildParamList方法(当然,无论它叫什么):