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

时间:2014-08-08 08:52:49

标签: c# system.data

我正在忙于构建用于数据检索和序列化的自定义框架,并且在定义专有数据库连接/命令/参数组合时遇到了问题。一切都按预期工作,直到我尝试将参数添加到我的自定义命令对象。我有一个基类,使用泛型函数处理查询准备和执行,如下所示:

/// <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函数中)添加到这个新类时,我看到{{1我的新类的属性是Parameters!它继承自基类并设置为只读,因此我无法自己初始化它。我的课程定义如下:

null

我已尝试在我的班级中明确覆盖属性public sealed class Connection : System.Data.Common.DbConnection,但无济于事 - 泛型函数仍然使用基类&#39; public new List<Parameter> Parameters { get; set; }财产。获取被覆盖属性的唯一方法是将Parameters(在command函数中)显式转换为我的自定义类型,这显然是我不想做的事情。< / p>

我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:0)

好的,我设法解决了这个问题。无法相信我整个上午都对此视而不见!在实现从System.Data.Common.DbCommand继承的新类时,您必须覆盖DbParameterCollection属性等。在我急于创建新类时,我刚刚在此属性的getter中返回null,我认为这是Parameters属性使用的内容。

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

答案 1 :(得分:0)

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

只能使用override关键字覆盖属性。在这种情况下,您无法覆盖Parameters,因为它不是虚拟的。

其次,DbCommand.Parameters只是protected abstract DbCommand.DbCommandParameterCollection属性上的外部接口。您需要实现此方法以返回实际的参数集合。