我想调用存储过程类型的command.ExecuteReader(),但我不希望我传递的参数名称与SP中的参数名称相同。以下是我正在尝试做的一个示例
SP:
ALTER PROCEDURE SPName
@Id nvarchar(50)
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM TableName
WHERE ColumnName = @Id
END
GO
代码:
using (SqlCommand command = new SqlCommand(spName, connection) { CommandType = CommandType.StoredProcedure })
{
command.parameters.Add(new SqlParameter(*paramaeter name*, sqlDbType.nvarchar){ Value = "SomeValue"};
}
答案 0 :(得分:2)
如果你想要一个通用的样式功能,而不需要额外的往返,你很乐意使用反射,你可以使用这样的东西。
// Return an array of SqlParameter's by using reflection on ParamObject
private static SqlParameter[] GetParametersFromObject( object ParamObject )
{
var Params = new List<SqlParameter>();
foreach( var PropInfo in ParamObject.GetType().GetProperties() )
{
Params.Add( new SqlParameter( PropInfo.Name, PropInfo.GetValue( ParamObject, null ) ) );
}
return Params.ToArray();
}
public static void ExecuteSP( SqlConnection Connection, string SPName, object ParamObject )
{
using( var Command = new SqlCommand() )
{
Command.Connection = Connection;
Command.CommandType = CommandType.StoredProcedure;
Command.CommandText = SPName;
Command.Parameters.AddRange( GetParametersFromObject( ParamObject ) );
// Command.ExecuteReader()...
}
}
这使用反射从匿名对象中获取属性名称和值以填充SqlCommand。这可以这样使用;
ExecuteSP( Conn, "GetStuff", new { Id = 7, Name = "Test" } );
这样,ExecuteSP是'通用',并且在调用ExecuteSP时选择参数名称和值。
答案 1 :(得分:1)
简单事实 - 您最终必须在调用存储过程时使用正确的参数名称,因为SQL Server按名称绑定参数(即使您使用EXEC调用SP而不使用命名参数,解析器也会从左侧按名称绑定它们)右)。
因此,如果您想使用其他名称,则需要在SqlCommand
和目标SP之间引入一个中间层。
但如果你只是不想关心这个名字并让它自动发现 - 那么你可以使用Conrad Frix中提到的技术在他SQL Server & .net support calling a stored procedure with param's values wihout providing param's names?的接受答案中 - 这就是为什么我标记为重复,因为它最终是您想要做的,即使原因不同。
答案 2 :(得分:1)
对于SqlServer,有一个DeriveParameters方法,该方法接受命令对象并在数据库中查询所请求存储过程的参数(名称和类型)。
然后,您可以迭代它们并提供值。
注意:这意味着额外访问数据库,因此如果您经常需要这样做,您可能希望缓存结果。
答案 3 :(得分:0)
下面的方法允许您编写用于调用存储过程的通用代码,但也使您可以灵活地为每个不同的存储过程执行特定操作
public delegate void SqlCOmmandDelegate(SqlCommand command);
public class Dal
{
public void ExecuteStoredProcedure(string procedureName,
SqlCommandDelgate commandDelegate)
{
using (SqlConnection connection = new SqlConnection())
{
connection.ConnectionString = GetConnectionString();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = procedureName;
connection.Open();
commandDelegate(command);
}
}
}
}
class UsesDal
{
public CallFirstProcedure(int value)
{
string userName;
ExecuteStoredProcedure("FIRST_PROCEDURE",
delegate(SqlCommand command)
{
command.Parameters.Add("UserID", value);
command.ExecuteReader();
//Do stuff with results e.g.
username = command.Parameters.Parameters["UserName"].ToString();
}
}
public CallOtherProcedure(string value)
{
int id;
ExecuteStoredProcedure("OTHER_PROCEDURE",
delegate(SqlCommand command)
{
command.Parameters.Add("ParameterName", value);
id = command.ExecuteScalar();
}
}
}