这是我的问题的详细信息。我创建了一个数据访问层类,它允许我创建与数据库(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 开发之前,我手动执行上述所有步骤,尽管所有对象(命令、连接等)都被明确声明为提供程序特定类型。从技术上讲,我正在使用与使用通用类型对象(不是特定于提供者)完全相同的场景。但我无法让它工作,在某个地方,可能,我错过了一些东西。