继承自System.Data.Common.DbCommand, Parameters属性为空

本文关键字:Parameters 属性 DbCommand System Data Common 继承 | 更新日期: 2023-09-27 18:16:59

我正忙着为数据检索和序列化构建一个自定义框架,在定义专有数据库连接/命令/参数组合时遇到了一个问题。在我尝试向自定义命令对象添加参数之前,一切都如预期的那样工作。我有一个基类,它处理查询的准备和执行与一个泛型函数如下:

/// <summary>
/// Prepares a command for execution.
/// </summary>
/// <typeparam name="C">The type of command to prepare</typeparam>
/// <typeparam name="P">The type of parameters to add to the command</typeparam>
/// <param name="query">The query to be prepared for the command</param>
/// <param name="parameters">Dictionary of parameters to be added to the command</param>
/// <returns>A prepared command to execute against a database</returns>
protected virtual C Prepare<C, P>(string query, Dictionary<string, object> parameters)
    where C : DbCommand, new()
    where P : DbParameter, new()
{
    if (Connection == null)
        throw new System.Exception("Database connector hasn't been initialized yet. Call .Initialize() first.");
    C command = new C()
    {
        CommandText = query,
        Connection = Connection
    };
    if (parameters != null)
    {
        foreach (KeyValuePair<string, object> kvp in parameters)
        {
            command.Parameters.Add(new P() // <-- Breaks right here!
            {
                ParameterName = kvp.Key,
                Value = kvp.Value
            });
        }
        parameters = null;
    }
    return command;
}

我已经为大多数提供程序类型(Ole, ADO, ODBC, Oracle等)实现了类,但它们是基于System.Data命名空间中提供的标准。net类型。我现在有一个完全自定义的类,继承了我想使用的System.Data.Common.DbCommand,但是当我尝试添加参数(在上面的Prepare函数中)到这个新类时,我看到我的新类的Parameters属性是null !它继承自基类并被设置为只读,所以我不能自己初始化它。我的类定义如下:

public sealed class Connection : System.Data.Common.DbConnection

我已经尝试显式覆盖属性在我的类作为public new List<Parameter> Parameters { get; set; },但无济于事-泛型函数仍然使用基类的Parameters属性。获得覆盖属性句柄的唯一方法是显式地将command(在Prepare函数中)转换为我的自定义类型,这显然是我不想做的。

我错过了什么吗?

继承自System.Data.Common.DbCommand, Parameters属性为空

首先,new不覆盖参数,它隐藏它。这意味着任何人使用DbCommand。参数将看到原始实现,而使用您的类型的任何人将看到您的实现。

重写属性只能使用override关键字完成。在这种情况下,您不能重写Parameters,因为它不是虚拟的。

第二,DbCommand.Parameters只是protected abstract DbCommand上的一个外部接口。DbCommandParameterCollection财产。您需要实现这个方法来返回一个实际的参数集合。

好的,我设法解决了这个问题。真不敢相信我整个早上都没发现!当实现从System.Data.Common.DbCommand继承的新类时,您必须覆盖DbParameterCollection属性等。在我急于创建新类时,我只是在此属性的getter中返回null,并且我认为这就是Parameters属性使用的内容。

所以我刚刚实现了一个继承自System.Data.Common.DbParameterCollection的新类,并在我的getter中返回了这个类的新实例,现在它正在工作!