0

这是我的问题的详细信息。我创建了一个数据访问层类,它允许我创建与数据库(Odbc、OleDb 和 SqlClient)通信所需的大部分对象。我还创建了一个业务对象处理层类,它大量使用反射来处理我的业务对象的大量任务。除其他外,该类生成我处理 DAL 所需的每个属性/对象(SQL 流、值列表、属性、设置检索值等)。看看下面的代码以获得进一步的解释:

    Public Shared Function InvokeParam(Of T)(_classObject As T, _commandType As AdapterCommandType, _arguments As Object()) As Boolean
        Dim s As String = DAL.SCRFL.GetParamStatement(_classObject, _commandType, _arguments)
        'Debug.Print(s)
        Dim hT As Hashtable = DAL.SCRFL.GetProperties(_classObject)
        Using cnn As IDbConnection = DataFactory.CreateConnection()
            Dim cmd As IDbCommand = DataFactory.CreateCommand(s, cnn)
            'cmd.CommandType = CommandType.Text
            cmd.CommandText = s
            For Each k In hT
                Dim param As IDbDataParameter = cmd.CreateParameter()
                'param.DbType = DataFactory.ConvertToDbType(k.value.GetType)

                param.Value = k.value
                param.ParameterName = k.key
                'param.Direction = ParameterDirection.Input

                'Debug.Print("value:={0}, name:={1}", TypeName(k.value), TypeName(k.key))
                Debug.Print("typeMatch:={0}, value:={1}, name:={2}", TypeName(param.Value) = TypeName(k.value), param.Value, param.ParameterName)

                cmd.Parameters.Add(param)
            Next
            If (cmd.ExecuteNonQuery > 0) Then
                Return True
            End If
        End Using
        Return False
    End Function

因此,DAL.SCRFL.GetParamStatement返回格式化INSERT INTO t1 (f1, f2, f3...) values (?, ?, ?...)为插入的字符串和更新、删除、选择语句的适当字符串。一切都是通过反思完成的。这里没有语法错误。我可以通过直接提供程序类型命令手动执行返回值。该DAL.SCRFL.GetProperties方法返回一个哈希表,格式为 key=property (field), value=field value。

现在,我需要为每个属性创建参数并将其添加到我的命令参数中,然后执行它。您将在我的代码中看到这种尝试(我通过循环哈希表为每个属性/值对创建参数)。但是最后我得到了一个例外的Data type mismatch in criteria expression.描述。我尝试将type属性添加到参数对象size等,但均不成功(我评论了它们)。我试图改变param.Value = k.value认为param.Value = If(IsDBNull(k.value), DBNull.Value, k.value)这可能是问题所在,尽管k.value来自我的商务舱并且我故意防止空值。没有任何效果!这是测试;业务类返回值来自DAL.SCRFL.GetParamStatement调用:对 OleDb/Access 数据库进行了测试,如您所见,我将备注字段用单引号括起来。我的反射方法读取类属性的属性(我将其设置为表字段名称)并DAL.SCRFL.GetParamStatement构建基本的 sql 语句以供插入、更新、删除和选择使用。AdapterCommandType是它的内置枚举类型)。

INSERT INTO Clinics 
(ClinicId, ClinicName, Phone, Fax, FederalId, DateContracted, Address, City, State, Zip, Inactive, [Memo], DateEntered, EnteredBy, DateModified, ModifiedBy) 
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 

请注意,我有另一种与此类似的方法,它执行一个 sql 语句 (InvokeSql),我在其中彻底检查每个属性的值类型,以在我的 sql 语句中构造 property=value 对。在此方法中使用完全限定的 sql 语句InvokeSql,方法可以在没有单个警告的情况下工作(粗略地说: sql 语句cnn As IDbConnection = CreateConnection(), cmd = CreateCommand(_cmdText, cnn), cmd.ExecuteNonQuery()在哪里_cmdText。没有参数,如您所见!)。我提到这一点是为了指出,每当我将参数与通用 IDbCommands 一起使用时,就会出现问题。即使在我的 DataFactory 中,IDbCommand 设置为提供者特定的命令类型(我DataFactory.CreateCommand(s, cnn)返回通用 IDbCommand)。

在我的 DAL 开发之前,我手动执行上述所有步骤,尽管所有对象(命令、连接等)都被明确声明为提供程序特定类型。从技术上讲,我正在使用与使用通用类型对象(不是特定于提供者)完全相同的场景。但我无法让它工作,在某个地方,可能,我错过了一些东西。

4

1 回答 1

0

我已经在 codeproject 上发布了这个问题,答案就在那里。 http://www.codeproject.com/Questions/446516/How-to-add-parameters-and-execute-a-generic-IDbCom

于 2012-08-25T17:46:52.507 回答