ADO.NET - 糟糕的做法?

Ech*_*lon 3 ado.net

几个月前我在MSDN上阅读一篇文章,并且最近开始使用以下代码片段来执行ADO.NET代码,但我觉得它可能很糟糕.我是在反应还是完全可以接受?

private void Execute(Action<SqlConnection> action)
{
    SqlConnection conn = null;
    try {
        conn = new SqlConnection(ConnectionString);
        conn.Open();
        action.Invoke(conn);
    } finally {
        if (conn != null && conn.State == ConnectionState.Open) {
            try {
                conn.Close();
            } catch {
            }
        }
    }
}

public bool GetSomethingById() {
    SomeThing aSomething = null
    bool valid = false;
    Execute(conn =>
    {
        using (SqlCommand cmd = conn.CreateCommand()) {
            cmd.CommandText = ....
            ...
            SqlDataReader reader = cmd.ExecuteReader();
            ...
            aSomething = new SomeThing(Convert.ToString(reader["aDbField"]));
        }
    });
    return aSomething;
}
Run Code Online (Sandbox Code Playgroud)

Cha*_*ion 8

当你能做到这一点时,有什么意义呢?

public SomeThing GetSomethingById(int id) 
{
    using (var con = new SqlConnection(ConnectionString)) 
    {
        con.Open();
        using (var cmd = con.CreateCommand()) 
        {
            // prepare command
            using (var rdr = cmd.ExecuteReader()) 
            {
                // read fields
                return new SomeThing(data);
            }
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以通过执行此类操作来促进代码重用.

public static void ExecuteToReader(string connectionString, string commandText, IEnumerable<KeyValuePair<string, object>> parameters, Action<IDataReader> action) 
{
    using (var con = new SqlConnection(connectionString)) 
    {
        con.Open();
        using (var cmd = con.CreateCommand()) 
        {
            cmd.CommandText = commandText;
            foreach (var pair in parameters) 
            {
                var parameter = cmd.CreateParameter();
                parameter.ParameterName = pair.Key; 
                parameter.Value = pair.Value; 
                cmd.Parameters.Add(parameter);
            }
            using (var rdr = cmd.ExecuteReader()) 
            {
                action(rdr);
            }
        } 
    }    
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

//At the top create an alias
using DbParams = Dictionary<string, object>;

ExecuteToReader(
    connectionString, 
    commandText, 
    new DbParams() { { "key1", 1 }, { "key2", 2 } }),
    reader => 
    {
        // ...
        // No need to dispose
    }
)
Run Code Online (Sandbox Code Playgroud)