2

我有一个带有很多方法的 dal 层,它们都调用存储过程,一些返回列表(所以使用SqlDataReader),其他的只有一个特定的值。

我有一个辅助方法可以创建SqlCommand

    protected SqlCommand CreateSprocCommand(string name, bool includeReturn, SqlDbType returnType)
    {
        SqlConnection con = new SqlConnection(this.ConnectionString);
        SqlCommand com = new SqlCommand(name, con);
        com.CommandType = System.Data.CommandType.StoredProcedure;

        if (includeReturn)
            com.Parameters.Add("ReturnValue", returnType).Direction = ParameterDirection.ReturnValue;

        return com;
    }

现在我的平均(过度简化)方法体看起来像:

SqlCommand cmd = CreateSprocCommand("SomeSprocName"); //an override of the above mentioned method
try {
   cmd.Connection.Open();
   using (var reader = cmd.ExecuteReader()) {
       //some code looping over the recors
   }
   //some more code to return whatever needs to be returned
}
finally {
   cmd.Connection.Dispose();
}

有没有办法重构它,这样我就不会失去我的辅助功能(它会做很多其他重复的工作),而且还能使用using

4

5 回答 5

13

一种方法是将其从返回命令更改为接受使用该命令的委托:

protected void ExecuteSproc(string name,
                            SqlDbType? returnType,
                            Action<SqlCommand> action)
{
    using (SqlConnection con = new SqlConnection(this.ConnectionString))
    using (SqlCommand com = new SqlCommand(name, con))
    {
        con.Open();
        com.CommandType = System.Data.CommandType.StoredProcedure;

        if (returnType != null)
        {
            com.Parameters.Add("ReturnValue", returnType.Value).Direction = 
                ParameterDirection.ReturnValue;
        }
        action(com);
    }
}

(请注意,我还删除了includeReturn参数并returnType改为可为空。只需传递null“无返回值”即可。)

您可以将其与 lambda 表达式(或匿名方法)一起使用:

ExecuteSproc("SomeName", SqlDbType.DateTime, cmd =>
{
    // Do what you want with the command (cmd) here
});

这样处理与创建在同一个地方,调用者不需要担心它。我非常喜欢这种模式——现在我们有了 lambda 表达式,它变得更加简洁了。

于 2009-05-26T08:29:25.903 回答
3

你可以这样做:

protected static SqlCommand CreateSprocCommand(SqlConnection con, string name, bool includeReturn, SqlDbType returnType)
{
    SqlCommand com = new SqlCommand(name, con);
    com.CommandType = System.Data.CommandType.StoredProcedure;

    if (includeReturn)
        com.Parameters.Add("ReturnValue", returnType).Direction = ParameterDirection.ReturnValue;

    return com;
}

并这样称呼它:

using (SqlConnection con = new SqlConnection(this.ConnectionString))
using (SqlCommand cmd = CreateSprocCommand(con, "SomeSprocName", true, SqlDbType.Int)
{
    cmd.Connection.Open();
    using (var reader = cmd.ExecuteReader())
    {
        //some code looping over the recors
    }
    //some more code to return whatever needs to be returned
}
于 2009-05-26T08:35:17.717 回答
1

您可以嵌套 using 语句:

using (SqlCommand cmd = CreateSprocCommand("..."))
{
  using (var connection = cmd.Connection)
  {
     connection.Open();
     using (var reader = cmd.ExecuteReader())
     {
         ...
     }
     ...
  }
}
于 2009-05-26T08:27:02.743 回答
0

怎么样:

using (SqlCommand cmd = CreateSprocCommand("whatever"))
{
  cmd.Connection.Open();
  using (var reader = cmd.ExecuteReader())
  {
   //blabla
  }
}
于 2009-05-26T08:25:02.933 回答
-1

你是这个意思吗 ?

using (SqlCommand cmd = CreateSprocCommand("SomeSprocName"))
{
    cmd.Connection.Open();
    using (var reader = cmd.ExecuteReader()) 
    {
        //some code looping over the recors
    }
}
于 2009-05-26T08:27:04.817 回答