我使用某个方法体调用存储过程,使用以下示例代码:
public void StoredProcedureThatIsBeingcalled(int variable_1, int variable_2, out DataSet ds)
{
using (SqlConnection con = new SqlConnection(DatabaseConnectionString))
{
ds = new DataSet("DsToGoOut");
using (SqlCommand cmd = new SqlCommand("StoredProcedureThatIsBeingcalled", DbConn.objConn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@variable_1", variable_1));
cmd.Parameters.Add(new SqlParameter("@variable_2", variable_2));
try
{
con.Open();
SqlDataAdapter objDataAdapter = new SqlDataAdapter();
objDataAdapter.SelectCommand = cmd;
objDataAdapter.Fill(ds);
con.Close();
}
catch (Exception ex)
{
//sql_log_err
}
}
}
}
有什么问题我上面的大部分代码都会在我的cs文件中一次又一次地重复我调用的每个不同的过程。
显然我可以将其清除并使用过程名称作为变量调用一个函数,但是如何为其提供不同数量的参数(具有不同的数据类型 - int,字符串bool - 从不其他任何内容)我使用的不同程序?
我可以使用不同数量的参数(0-10)来设置几个不同的函数,但我觉得有更好的方法可以做到这一点吗?
答案 0 :(得分:4)
我有这个问题;我在多个数据库上调用存储过程。您可以存储存储过程详细信息,例如数据库表中的名称,输入参数,输出参数等,然后使用工厂方法填充对象(下例中的clsStoredProcedure)。代码看起来像这样(我没有测试过代码):
public void StoredProcedureThatIsBeingcalled(clsStoredProcedure objStoredProcedure)
{
using (SqlConnection con = new SqlConnection(objStoredProcedure.ConnectionString))
{
ds = new DataSet("DsToGoOut");
using (SqlCommand cmd = new SqlCommand(objStoredProcedure.Name, DbConn.objConn))
{
cmd.CommandType = CommandType.StoredProcedure;
foreach (Parameter p in clsStoredProcedure.Parameters)
{
cmd.Parameters.Add(new SqlParameter(p.name, p.value));
}
try
{
con.Open();
SqlDataAdapter objDataAdapter = new SqlDataAdapter();
objDataAdapter.SelectCommand = cmd;
objDataAdapter.Fill(ds);
con.Close();
}
catch (Exception ex)
{
//sql_log_err
}
}
}
}
如果要连接到Oracle数据库和SQL数据库,则可以使用dbConnection,dbCommand等连接到数据库。
答案 1 :(得分:4)
我知道这是一个非常古老的问题(实际上,我在找到另一个旧的答案时偶然发现了它,我给了别人关闭作为复制品),但我最近mail回答了这个问题。 。 它通过封装Connection,Command,Parameters和DataAdapter来最小化使用ADO.Net时的代码重复 如果你想尝试一下,我会很高兴知道你对它的看法。
您可以使用辅助类来封装sql参数,并创建一个方法来处理所有数据集填充:
助手类:
public DataSet ExecuteSelectProcedure(string procedeureName, params SqlParamDefinition[] parameters)
{
var ds = new DataSet();
using (var con = new SqlConnection(DatabaseConnectionString))
{
using (var cmd = new SqlCommand(procedeureName, DbConn.objConn))
{
cmd.CommandType = CommandType.StoredProcedure;
for(int i = 0; i < parameters.Length; i++)
{
var param = parameters[i];
cmd.Parameters.Add(new SqlParameter(param.Name, param.DbType).Value = param.Value);
}
try
{
con.Open();
var objDataAdapter = new SqlDataAdapter();
objDataAdapter.SelectCommand = cmd;
objDataAdapter.Fill(ds);
con.Close();
}
catch (Exception ex)
{
//sql_log_err
}
}
}
return ds;
}
执行方法(基于您发布的方法):
var parameters = new SqlParamDefinition[]
{
new SqlParamDefinition("@Param1", SqlDbType.VarChar, "value1"),
new SqlParamDefinition("@Param2", SqlDbType.VarChar, "value2"),
new SqlParamDefinition("@Param3", SqlDbType.Int, 123),
};
var ds = ExecuteSelectProcedure("Strong procedure name", parameters);
调用示例:
operator unsigned long()
答案 2 :(得分:3)
您可以创建接受string
和Dictionary<string,object>
作为参数的方法。现在您可以根据命令文本和参数字典构建命令。此外,您可以扩展此方法并将其用于选择,插入等查询。
示例:
private void ExecCommand(string commandText, Dictionary<string, object> param)
{
using (SqlConnection con = new SqlConnection(DatabaseConnectionString))
{
ds = new DataSet("DsToGoOut");
using (SqlCommand cmd = new SqlCommand(commandText, DbConn.objConn))
{
cmd.CommandType = CommandType.StoredProcedure;
//***************************************
// New method
cmd = AddParametersToCommand(cmd, param);
//***************************************
try
{
con.Open();
SqlDataAdapter objDataAdapter = new SqlDataAdapter();
objDataAdapter.SelectCommand = cmd;
objDataAdapter.Fill(ds);
con.Close();
}
catch (Exception ex)
{
//sql_log_err
}
}
}
}
AddParametersToCommand
:
private SQLCommand AddParametersToCommand(SqlCommand command, Dictionary<string, object> parameters)
{
if (parameters == null || command == null)
{
return;
}
SQLCommand tempCommand = command;
foreach (var param in parameters)
{
var parameter = tempCommand.CreateParameter();
parameter.ParameterName = param.Key;
parameter.Value = param.Value ?? DBNull.Value;
tempCommand.Parameters.Add(parameter);
}
return tempCommand;
}
并使用它:
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("@variable_1", variable_1);
parameters.Add("@variable_2", variable_2);
ExecCommand("StoredProcedureThatIsBeingcalled", parameters);
答案 3 :(得分:2)
所以,
您可以使用dapper执行存储过程。 https://github.com/StackExchange/dapper-dot-net
您可以声明将使用您在存储过程中选择的内容映射的DTO模型。
public class DogDto
{
public int? Age { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public float? Weight { get; set; }
public int IgnoredProperty { get { return 1; } }
}
// _databaseConnectionString is your database connection string
using (var conn = new SqlConnection(_databaseConnectionString)){
var dog = cnn.Query<DogDto>("schema.spGetDog", new {Id = 120},
commandType: CommandType.StoredProcedure).SingleOrDefault();
}
// and let's assume we have schema.spGetDog stored procedure already declared in our database
// and be aware that the 2nd parameter after the stored procedure name are the stored procedure parameters
您的存储过程必须选择Age,Id,Name,Weight列(通过属性名称实现映射)。我真的不知道你是否可以更改这个comportment,因为如果你在使用存储过程的database / dto中有相同的列/属性,那么开发过程会更快。
仅仅是为了记录,根据文档:“Dapper没有特定于DB的实现细节,它适用于所有.NET ADO提供程序,包括SQLite,SQL CE,Firebird,Oracle,MySQL,PostgreSQL和SQL Server。 “
这就是你需要做的一切。