你会如何重构这段代码?

时间:2009-11-19 23:07:56

标签: c# compact-framework refactoring

这段代码在Windows Compact Framework上运行,它的作用很明显。看起来它应该被重构(特别是考虑到我可能想稍后添加cmd.ExecuteResultSet()),但我看不到一种优雅的方式来做到这一点。任何想法都赞赏。

internal void RunNonQuery(string query)
{
    string connString = GetLocalConnectionString();

    using (SqlCeConnection cn = new SqlCeConnection(connString))
    {
        cn.Open();
        SqlCeCommand cmd = cn.CreateCommand();
        cmd.CommandText = query;
        cmd.ExecuteNonQuery();
    }
}  

internal int RunScalar(string query)  
{
    string connString = GetLocalConnectionString();

    using (SqlCeConnection cn = new SqlCeConnection(connString))
    {
        cn.Open();
        SqlCeCommand cmd = cn.CreateCommand();
        cmd.CommandText = query;
        return int.Parse(cmd.ExecuteScalar().ToString());
    }
}

3 个答案:

答案 0 :(得分:5)

我不确定我重构它,但也许:

static void PerformQuery(string connectionString, string command,
      Action<SqlCeCommand> action)
{ //TODO: sanity checks...
    using(SqlCeConnection conn = new SqlCeConnection(connectionString))
    using(SqlCeCommand cmd = conn.CreateCommand()) {
        cmd.CommandText = command;
        conn.Open();
        action(cmd);
    }
}

internal void RunNonQuery(string query)
{
    string connString = GetLocalConnectionString();
    PerformQuery(connString, query, cmd => cmd.ExecuteNonQuery());
}  

internal int RunScalar(string query)  
{
    int result = 0;
    string connString = GetLocalConnectionString();
    PerformQuery(connString, query,
        cmd => {result = int.Parse(cmd.ExecuteScalar().ToString()); }
    );
    return result;
}

否则 - 可能只是CreateAndOpenConnection(string)方法和CreateCommand(SqlCeConnection,string)方法。

答案 1 :(得分:2)

如果您使用的是C#3.0,则可以执行以下操作:

private T CreateCommand<T>(string query, Func<SqlCeCommand, T> func)
{
    var connString = GetLocalConnectionString();

    using (var cn = new SqlCeConnection(connString))
    {
        cn.Open();

        using (var cmd = cn.CreateCommand())
        {
            cmd.CommandText = query;
            return func(cmd);
        }
    }
}

private void CreateCommand(string query, Action<SqlCeCommand> action)
{
    CreateCommand<object>(query, cmd => 
    {
        action(cmd);
        return null;
    });
}

internal void RunNonQuery(string query)
{
    CreateCommand(query, cmd => cmd.ExecuteNonQuery());
}

internal int RunScalar(string query)
{
    return CreateCommand(query, cmd => 
        int.Parse(cmd.ExecuteScalar().ToString()));
}    

答案 2 :(得分:2)

我会从代码中创建一个类来包装连接创建和命令执行逻辑。这将为您提供在未来实现事务的单一位置,并将合并连接和命令的创建。此合并将允许设置超时,加入事务等。

class Connection : IDisposable
{
    readonly SqlConnection _conn;
    public Connection()
    {
        string connString = GetLocalConnectionString();
        _conn = new SqlConnection(connString);
        _conn.Open();
    }

    public void Dispose() { _conn.Dispose(); }

    public SqlCommand CreateCommand(string qry)
    {
        SqlCommand cmd = _conn.CreateCommand();
        cmd.CommandText = qry;
        //cmd.CommandTimeout = TimeSpan.FromMinutes(x);
        return cmd;
    }
    public int ExecuteNonQuery(string qry)
    {
        using (SqlCommand cmd = CreateCommand(qry))
            return cmd.ExecuteNonQuery();
    }
    public int RunScalar(string qry)
    {
        using (SqlCommand cmd = CreateCommand(qry))
            return int.Parse(cmd.ExecuteScalar().ToString());
    }
}

然后,如果您仍想维护原始API,请执行以下操作:

class SqlCode
{
    internal void RunNonQuery(string query)
    {
        using (Connection cn = new Connection())
            cn.ExecuteNonQuery(query);
    }

    internal int RunScalar(string query)
    {
        using (Connection cn = new Connection())
            return cn.RunScalar(query);
    }
}

唯一剩下的就是在SqlXxxx中重新插入'Ce';)