我正在忙于构建用于数据检索和序列化的自定义框架,并且在定义专有数据库连接/命令/参数组合时遇到了问题。一切都按预期工作,直到我尝试将参数添加到我的自定义命令对象。我有一个基类,使用泛型函数处理查询准备和执行,如下所示:
/// <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>
我在这里错过了什么吗?
答案 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属性上的外部接口。您需要实现此方法以返回实际的参数集合。