2017-12-12 8 views
0

データベースに簡単にアクセスできるmssql-context-classがあります。またc#genereic sql context patameter

var context = MsSqlContext.CreateFrom("some_connectionstring"); 

context.Insert("myTable", parameters => { 
    parameters.AddWithValue("foo_1", "bar_1"); 
    parameters.AddWithValue("foo_2", "bar_2"); 
}); 

今私がいることができ、汎用のSQLコンテキスト・クラスを構築したい:次のようになり、これを呼び出す

public int? Insert(string tableName, Action<SqlParameterCollection> actionSqlParameterCollection) 
{ 
    using (var sqlConnection = new SqlConnection(ConnectionString)) 
    { 
     sqlConnection.Open(); 

     using (var sqlCommand = sqlConnection.CreateCommand()) 
     { 
      var commandText = $"insert into {tableName} (@columns) output inserted.id values (@values)"; 

      var valueBuilder = new StringBuilder(); 
      var columnBuilder = new StringBuilder(); 

      actionSqlParameterCollection?.Invoke(sqlCommand.Parameters); //Fill the parameters from outside with some values 

      foreach (SqlParameter parameter in sqlCommand.Parameters) 
      { 
       valueBuilder.Append($",@{parameter.ParameterName}"); 
       columnBuilder.Append($",{parameter.ParameterName}"); 
      } 

      commandText = commandText.Replace("@values", valueBuilder.ToString().Substring(1)); 
      commandText = commandText.Replace("@columns", columnBuilder.ToString().Substring(1)); 


      sqlCommand.CommandText = commandText; 

      object result = sqlCommand.ExecuteScalar(); 

      return (int?)result; 
     } 
    } 
} 

:それはこのようになりますよう、データローを挿入するための機能が含まれていますmysql-databasesを処理します。

var context = SqlContext.CreateFrom(SqlProvider.MySql, "Server=localhost;Database=4713_demo;Uid=root;Pwd=;"); 

context.Insert("my_table", parameters => 
{ 
    parameters.Add(?); //It expects an object 
}); 

私の問題は

context.Insert("my_table", parameters => 
{ 
    parameters.Add(context.CreateParameter("foo","bar")); 
}); 
ような何かをしたくない、である:私は、それはこのようになります関数を呼び出すしようとすると

public int? Insert(string tableName, Action<IDataParameterCollection> actionParameterCollection) 
{ 
    using (var connection = this.CreateConnection()) 
    { 
     using (var command = connection.CreateCommand()) 
     { 
      var commandText = $"insert into {tableName} (@field) values (@values)"; 

      var valueBuilder = new StringBuilder(); 
      var columnBuilder = new StringBuilder(); 

      actionParameterCollection?.Invoke(command.Parameters); 

      foreach (IDbDataParameter parameter in command.Parameters) 
      { 
       valueBuilder.Append($",@{parameter.ParameterName}"); 
       columnBuilder.Append($",{parameter.ParameterName}"); 
      } 

      commandText = commandText.Replace("@values", valueBuilder.ToString().Substring(1)); 
      commandText = commandText.Replace("@columns", columnBuilder.ToString().Substring(1)); 


      command.CommandText = commandText; 

      object result = command.ExecuteScalar(); 

      return (int?)result; 

     } 
    } 
} 

:挿入機能は、これまでのところ、このようになります。

パラメータ名とパラメータ値を渡したいだけです。コンテキストクラス自体がプロバイダを認識しており、パラメータを作成する必要があります。それを買う方法は?

+0

あなたがそれを望んでいないのはなぜ? "parameters.Add(context.CreateParameter(" foo "、" bar "));" – lucky

答えて

0

解決策は、このSqlParameterizerクラスです。このクラスを使用して

public class SqlParameterizer 
{ 
    private SqlProvider Provider { get; set; } 
    private List<IDbDataParameter> ParameterList { get; set; } 

    public SqlParameterizer(SqlProvider sqlProvider) 
    { 
     this.Provider = sqlProvider; 
     this.ParameterList = new List<IDbDataParameter>(); 
    } 


    public void Add(string parameterName, object parameterValue) 
    { 
     switch(this.Provider) 
     { 
      case SqlProvider.MsSql: 
       this.ParameterList.Add(new SqlParameter(parameterName, parameterValue)); 
       break; 
      case SqlProvider.MySql: 
       this.ParameterList.Add(new MySqlParameter(parameterName, parameterValue)); 
       break; 
      case SqlProvider.OracleSql: 
       throw new Exception($"SqlProvider '{this.Provider}' not supported yet..."); 
      default: 
       throw new Exception($"Unknown SqlProvider '{this.Provider}'"); 
     } 
    } 
    public IDbDataParameter[] GetParameters() 
    { 
     return ParameterList.ToArray(); 
    } 


} 

は、次のようになります。

var commandText = $"insert into {tableName} (@columns) values (@values)"; 

var valueBuilder = new StringBuilder(); 
var columnBuilder = new StringBuilder(); 
var parameterizer = new SqlParameterizer(this.Provider); 

actionValueParameterizer?.Invoke(parameterizer); 

foreach(IDbDataParameter parameter in parameterizer.GetParameters()) 
{ 
    command.Parameters.Add(parameter); 
    valueBuilder.Append($",@{parameter.ParameterName}"); 
    columnBuilder.Append($",{parameter.ParameterName}"); 
} 

commandText = commandText.Replace("@values", valueBuilder.ToString().Substring(1)); 
commandText = commandText.Replace("@columns", columnBuilder.ToString().Substring(1)); 

command.CommandText = commandText; 

command.ExecuteNonQuery(); 

は私の挿入機能を呼び出す:

context.Insert("some_table", parameterizer => 
{ 
    parameterizer.Add("some_column", "some_value"); 
});