2009-08-27 80 views
3

我有一個DAO類,我正在使用它來執行數據庫操作。我有很多從不同的方法/函數調用的存儲過程。在每個函數/方法中,我正在寫單行來爲SP添加參數值。有沒有什麼辦法可以封裝這個,這樣所有的函數/方法都可以調用這個封裝的函數來傳遞參數給不同的存儲過程。我相信你們中的很多人都在做類似的事情。基本上我試圖避免向參數集合中添加參數的冗餘語句。如何封裝存儲過程調用

(我使用C#3.5)

回答

1

事情是這樣的,也許:

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

編輯:既然你已經添加評論說你需要支持輸出參數,可以繼承人另一種方法從同一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

實際上,我們使用通用的自定義參數列表,通過實際的dal中的方法來簡化它。我在示例中使用了一本字典,但您也可以擁有一個List ,其中參數封裝了您的方向和其他屬性。 – grenade

+0

非常感謝這段代碼。我想我會趕上來:) – pradeeptp