3

在我们拥有的每个 ADO.NET 连接器上AddWithValue,因此添加参数变得轻而易举。令我惊讶的是,这种重载IDataParameterCollectionDbParameterCollection. 在编写与供应商无关的层(针对接口进行编码)时,如何以最少的麻烦(来自调用方和被调用方)实现相同的目标?

现在我做:

public void Execute(string query, Action<IDbCommand> parameterizer)

Execute(query, cmd =>
    {
        var param = cmd.CreateParameter();
        param.ParameterName = "user_id";
        param.Value = 1;
        cmd.Parameters.Add(param);

        param = cmd.CreateParameter();
        param.ParameterName = "mf";
        param.Value = "6CE71037";
        cmd.Parameters.Add(param);
    });

这工作量太大了吧。否则我可以更改签名:

public void Execute(string query, IEnumerable<KeyValuePair<string, object>> parameters)

var parameters = new Dictionary<string, object> 
                 { { "user_id", 1 }, { "mf", "6CE71037" } };
Execute(query, parameters);

Execute这种方法需要我在被调用者(方法)中编写另一个循环。这几乎是我想要的,但只是看看是否有更简洁的方法。例如像这样:

public void Execute(string query, Action<IDataParameterCollection> parameterizer)

Execute(query, p =>
    {
        p["user_id"] = 1;
        p["mf"] = "6CE71037";
    });

这给出了一个运行时异常说Unable to cast object of type 'System.Int32' to type 'System.Data.Common.DbParameter。我理解错误。只是想知道是否有更优雅的模式..

4

1 回答 1

7

为什么不在最后一个签名中使用字典:

public void Execute(string query, Action<Dictionary<string, object>> parameterizer)

Execute(query, p =>
    {
        p["user_id"] = 1;
        p["mf"] = "6CE71037";
    });

然后,该Execute方法可以使用Action填充 aDictionary并基于它创建参数:

var parameters = new Dictionary<string, object>();
parametrizer(parameters);
foreach (var pair in parameters)
{
    var parameter = f.CreateParameter();
    parameter.ParameterName = pair.Key;
    parameter.Value = pair.Value;
    cmd.Parameters.Add(parameter);
}

如果要传递实际值,另一种解决方案IDbCommand是使用扩展方法

public static void AddWithValue<T>(this IDbCommand command, string name, T value)
{
    var parameter = command.CreateParameter();
    parameter.ParameterName = name;
    parameter.Value = value;
    command.Parameters.Add(parameter);
}

调用它看起来像:

Execute(query, cmd =>
    {
        cmd.AddWithValue("user_id", 1);
        cmd.AddWithValue("mf", "6CE71037");
    });
于 2013-02-13T13:19:40.263 回答