2009-08-27 18 views
3

データベース操作を行うために使用しているDAOクラスがあります。私は、さまざまなメソッド/関数から呼び出す多くのストアドプロシージャを持っています。すべての関数/メソッドで、SPのパラメータ値を追加するための1行を記述しています。これをカプセル化して、すべての関数/メソッドがこの1つのカプセル化された機能を呼び出して、異なるストアドプロシージャにパラメータを渡せるようにする方法はありますか?私はあなたの多くがこれに似た何かに取り組んできたと確信しています。基本的には、パラメータをパラメータコレクションに追加するための冗長な文を避けようとしています。ストアドプロシージャコールをカプセル化する方法

多分このような

答えて

1

何か(私はC#3.5使用しています):

public static IDataReader GetDataReader(string connectionStringKey, string storedProcedure, Dictionary<string, object> parameters) { 
    try { 
     SqlCommand command = GetCommandWithConnection(connectionStringKey); 
     command.CommandText = storedProcedure; 
     command.CommandType = CommandType.StoredProcedure; 
     foreach (var parameter in parameters ?? new Dictionary<string, object>()) 
      command.Parameters.AddWithValue(parameter.Key, parameter.Value); 
     command.Connection.Open(); 
     return command.ExecuteReader(); 
    } 
    catch (Exception e) { 
     Log.Error(string.Format("Error in GetDataReader, executing sp: {0}", storedProcedure), e); 
     throw; 
    }  
} 
private static SqlCommand GetCommandWithConnection(string connectionStringKey) { 
    return new SqlConnection(GetConnectionString(connectionStringKey)).CreateCommand(); 
} 
private static string GetConnectionString(string connectionStringKey) { 
    return ConfigurationManager.ConnectionStrings[connectionStringKey].ToString(); 
} 

編集:あなたは、出力のparamsをサポートする必要が言うには、コメントを追加しましたから、同じからHERESに別の方法をDALクラス:

public static T GetScalar<T>(string connectionStringKey, string storedProcedure, Parameters parameters) { 
    try { 
     List<Parameter> outs = null; 
     SqlCommand command = GetCommandWithConnection(connectionStringKey); 
     command.CommandText = storedProcedure; 
     command.CommandType = CommandType.StoredProcedure; 
     if (parameters != null) { 
      outs = parameters.FindAll(p => p.Direction != ParameterDirection.Input); 
      parameters.ForEach(p => command.Parameters.AddWithValue(p.Key, p.Value).Direction = p.Direction); 
     } 
     command.Connection.Open(); 
     object o = command.ExecuteScalar(); 
     T result = (o != null) ? (T)o : default(T); 
     if (outs != null && outs.Count > 0) { 
      foreach (Parameter parameter in outs) { 
       SqlParameter sqlParameter = command.Parameters[parameter.Key]; 
       parameters[parameter.Key] = (sqlParameter.Value == DBNull.Value) ? null : sqlParameter.Value; 
      } 
     } 
     command.Connection.Close(); 
     if (o == null && (typeof(T) == typeof(int)) && parameters != null && parameters.ContainsKey("RowCount")) 
      result = (T)parameters["RowCount"]; 
     return result; 
    } 
    catch (Exception e) { 
     Log.Error(String.Format("Error in GetScalar<{0}>, executing sp: {1}", typeof(T).Name, storedProcedure), e); 
     throw; 
    } 
} 

とサポートパラメータクラス:

public class Parameter{ 
    public string Key { get; private set; } 
    public object Value { get; protected internal set; } 
    public ParameterDirection Direction { get; protected internal set; } 
    public Parameter(string key, object value) : this(key, value, ParameterDirection.Input) { } 
    public Parameter(string key, object value, ParameterDirection direction){ 
     Key = key; 
     Value = value; 
     Direction = direction; 
    } 
} 
public class Parameters : List<Parameter>{ 
    public Parameters() { } 
    public Parameters(object o){ 
     Populate(o); 
    } 
    public void Add(string key, object value){ 
     if (ContainsKey(key)) 
      throw new Exception("Parameter with the specified key already exists."); 
     Add(new Parameter(key, value)); 
    } 
    public void Add(string key, object value, ParameterDirection direction){ 
     if (ContainsKey(key)) 
      throw new Exception("Parameter with the specified key already exists."); 
     Add(new Parameter(key, value, direction)); 
    } 
    public bool ContainsKey(string key){ 
     return (Find(p => p.Key == key) != null); 
    } 
    protected internal int GetIndex(string key){ 
     int? index = null; 
     for (int i = 0; i < Count; i++){ 
      if (this[i].Key == key){ 
       index = i; 
       break; 
      } 
     } 
     if (index == null) 
      throw new IndexOutOfRangeException("Parameter with the specified key does not exist."); 
     return (int)index; 
    } 
    public object this[string key]{ 
     get { return this[GetIndex(key)].Value; } 
     set { this[GetIndex(key)].Value = value; } 
    } 
    private void Populate<T>(T obj){ 
     foreach (KeyValuePair<string, object> pair in new ObjectProperties(obj, BindingFlags.Public | BindingFlags.Instance)) 
      Add(pair.Key, pair.Value); 
    } 
} 
+0

ありがとうございました。私はまた、パラメータがIn型かOut型かという情報を渡す方法を理解しようとしていますか? – pradeeptp

+0

私はこれを実際のメソッドで単純化しました。ここでは汎用のカスタムパラメータリストを使用します。私はこの例では辞書を使っていましたが、List というパラメータを使って、方向やその他のプロパティをパラメータでカプセル化することもできます。 – grenade

+0

このコードをありがとうございました。私はここから追いつくだろう:) – pradeeptp

関連する問題