将代码重构为 using 语句

发布于 2024-07-22 04:54:35 字数 1069 浏览 11 评论 0原文

我有一个包含很多方法的 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 吗?

I have a dal layer with lots of methods, all of them call stored procedures, some return lists (so with a use of SqlDataReader), others only a specific value.

I have a helper method that creates the 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;
    }

Now my average (overly simplified) method body look like:

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();
}

Is there a way to refactor this, so that I won't lose my helper function (it does quite a bit of otherwise repetitive work), and yet be able to use using?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一抹苦笑 2024-07-29 04:54:35

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

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 表达式,它变得更加简洁。

One way is to change it from returning a command to taking a delegate which uses the command:

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);
    }
}

(Note that I've also removed the includeReturn parameter and made returnType nullable instead. Just pass null for "no return value".)

You'd use this with a lambda expression (or anonymous method):

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

That way the disposal is in the same place as the creation, and the caller just doesn't need to worry about it. I'm becoming quite a fan of this pattern - it's a lot cleaner now that we've got lambda expressions.

熊抱啵儿 2024-07-29 04:54:35

你可以这样做:

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
}

You can do this:

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;
}

and call it like this:

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
}
云淡月浅 2024-07-29 04:54:35

您可以嵌套使用语句:

using (SqlCommand cmd = CreateSprocCommand("..."))
{
  using (var connection = cmd.Connection)
  {
     connection.Open();
     using (var reader = cmd.ExecuteReader())
     {
         ...
     }
     ...
  }
}

You can nest using statements:

using (SqlCommand cmd = CreateSprocCommand("..."))
{
  using (var connection = cmd.Connection)
  {
     connection.Open();
     using (var reader = cmd.ExecuteReader())
     {
         ...
     }
     ...
  }
}
吲‖鸣 2024-07-29 04:54:35

怎么样:

using (SqlCommand cmd = CreateSprocCommand("whatever"))
{
  cmd.Connection.Open();
  using (var reader = cmd.ExecuteReader())
  {
   //blabla
  }
}

How about:

using (SqlCommand cmd = CreateSprocCommand("whatever"))
{
  cmd.Connection.Open();
  using (var reader = cmd.ExecuteReader())
  {
   //blabla
  }
}
凉风有信 2024-07-29 04:54:35

你是这个意思吗 ?

using (SqlCommand cmd = CreateSprocCommand("SomeSprocName"))
{
    cmd.Connection.Open();
    using (var reader = cmd.ExecuteReader()) 
    {
        //some code looping over the recors
    }
}

Is this what you mean ?

using (SqlCommand cmd = CreateSprocCommand("SomeSprocName"))
{
    cmd.Connection.Open();
    using (var reader = cmd.ExecuteReader()) 
    {
        //some code looping over the recors
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文