2009-11-19 3 views
1

Этот бит кода работает на 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()); 
    } 
} 
+0

В статически типизированном языке без хорошей макросистемы это выглядит очень тяжело для меня. – Svante

ответ

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).

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

Я хотел бы создать класс из кода, чтобы обернуть логику создания соединения и выполнения команд. Это обеспечит вам единое место для реализации транзакций в будущем и консолидирует создание соединения и команды. Такая консолидация позволит настройки таймаута, вступив транзакции и т.д.

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

Единственное, что осталось, чтобы повторно -включить «Ce» в материал SqlXxxx;)

Смежные вопросы