3
我有一個DAO類,我正在使用它來執行數據庫操作。我有很多從不同的方法/函數調用的存儲過程。在每個函數/方法中,我正在寫單行來爲SP添加參數值。有沒有什麼辦法可以封裝這個,這樣所有的函數/方法都可以調用這個封裝的函數來傳遞參數給不同的存儲過程。我相信你們中的很多人都在做類似的事情。基本上我試圖避免向參數集合中添加參數的冗餘語句。如何封裝存儲過程調用
(我使用C#3.5)
我有一個DAO類,我正在使用它來執行數據庫操作。我有很多從不同的方法/函數調用的存儲過程。在每個函數/方法中,我正在寫單行來爲SP添加參數值。有沒有什麼辦法可以封裝這個,這樣所有的函數/方法都可以調用這個封裝的函數來傳遞參數給不同的存儲過程。我相信你們中的很多人都在做類似的事情。基本上我試圖避免向參數集合中添加參數的冗餘語句。如何封裝存儲過程調用
(我使用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();
}
編輯:既然你已經添加評論說你需要支持輸出參數,可以繼承人另一種方法從同一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);
}
}
感謝您的這種建議。我也想弄清楚如何傳遞參數是In或Out類型的信息? – pradeeptp
實際上,我們使用通用的自定義參數列表,通過實際的dal中的方法來簡化它。我在示例中使用了一本字典,但您也可以擁有一個List,其中參數封裝了您的方向和其他屬性。 –
grenade
非常感謝這段代碼。我想我會趕上來:) – pradeeptp