简体   繁体   中英

How to encapsulate Stored Procedure call

I have a DAO class which I am using to do database operations. I have lots of Stored Procedures that I call from different methods/functions. In every functions/Method, I am writing single line for adding parameter values for the SPs. Is there any way I can encapsulate this so that all the functions/Methods can call this one encapsulated functionality to pass parameters to Different stored procedure. I am sure many of you have worked on somthing similar to this. Basically I am trying to avoid redundant statements for adding parameters to parameters collection.

(I am using C# 3.5)

Something like this maybe:

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

Edit: since you've added comments to say you need to support output params, heres another method from the same dal class:

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

And the supporting Parameter classes:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM