Voici mon problème en détail. J'ai créé une classe de couche d'accès aux données qui me permet de créer la plupart des objets dont j'avais besoin pour communiquer avec des bases de données (Odbc, OleDb et SqlClient). J'ai également créé une classe de couche de gestion d'objet métier avec une utilisation intensive de Reflection pour gérer beaucoup de tâches avec mes objets métier. Entre autres choses, cette classe génère chaque propriété/objet dont j'ai besoin pour ma gestion de la couche DAL (flux SQL, liste de valeurs, propriétés, définition de valeurs de récupération, etc.). Jetez un coup d'oeil le code ci-dessous pour plus d'explications:Comment ajouter des paramètres et exécuter un IDbCommand générique
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
Ainsi, la chaîne DAL.SCRFL.GetParamStatement
de retour en forme comme INSERT INTO t1 (f1, f2, f3...) values (?, ?, ?...)
pour l'insertion et les chaînes appropriées pour la mise à jour, supprimer les instructions select. Tout est fait avec la réflexion. Il n'y a pas d'erreur de syntaxe ici. Je peux exécuter manuellement les valeurs renvoyées via des commandes de type fournisseur direct. La méthode DAL.SCRFL.GetProperties
renvoie une table de hachage au format clé = propriété (champ), valeur = valeur du champ.
Maintenant, j'ai besoin de créer des paramètres pour chaque propriété et de l'ajouter à mes paramètres de commande, puis de l'exécuter. Cette tentative apparaîtra dans mon code (je crée des paramètres pour chaque couple propert/value en bouclant la table de hachage). Cependant, à la fin, je reçois une exception avec la description Data type mismatch in criteria expression.
. J'ai essayé d'ajouter la propriété type
à l'objet de paramètre, size
etc, tout a échoué (je les ai commentés). J'ai essayé de changer param.Value = k.value
à param.Value = If(IsDBNull(k.value), DBNull.Value, k.value)
en pensant que cela pourrait être le problème, bien que k.value
soit de ma classe d'affaires et j'empêche intentionnellement des valeurs nulles. Rien n'a fonctionné! voici le test; La classe commerciale a renvoyé la valeur DAL.SCRFL.GetParamStatement
call: Le test est effectué pour la base de données OleDb/Access et, comme vous pouvez le voir, j'ai joint le champ Mémo entre guillemets simples. Mes méthodes de réflexion lisent les attributs des propriétés de classe (que je définis comme étant des noms de champs de tables) et DAL.SCRFL.GetParamStatement
construit des instructions sql de base pour insérer, mettre à jour, supprimer et sélectionner l'utilisation. AdapterCommandType
est un type construit enum pour cela).
INSERT INTO Clinics
(ClinicId, ClinicName, Phone, Fax, FederalId, DateContracted, Address, City, State, Zip, Inactive, [Memo], DateEntered, EnteredBy, DateModified, ModifiedBy)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Notez que j'ai une autre méthode similaire à celle qui exécute une instruction SQL (InvokeSql) où je vérifie soigneusement les types de valeur pour chaque propriété pour construire des paires propriété = valeur dans mon instruction SQL. En utilisant une instruction sql pleinement qualifiée, InvokeSql
, la méthode fonctionne sans un seul avertissement (Rouphly: cnn As IDbConnection = CreateConnection(), cmd = CreateCommand(_cmdText, cnn), cmd.ExecuteNonQuery()
où _cmdText
est l'instruction sql.) Pas de paramètres comme vous pouvez le voir!). Je mentionne ceci pour indiquer que le problème surgit chaque fois que j'utilise des paramètres avec IDbCommands génériques. Même si dans mon DataFactory, IDbCommand est défini comme type de commande spécifique au fournisseur (mon DataFactory.CreateCommand(s, cnn)
renvoie IDbCommand générique). Avant mon développement DAL, je faisais toutes les étapes ci-dessus manuellement, bien que tous les objets (commandes, connexions, etc.) aient été explicitement déclarés comme étant des types spécifiques au fournisseur. Techniquement parlant, j'exerce exactement les mêmes scénarios que je le faisais pour les types génériques d'objets (pas spécifiques au fournisseur). Mais je ne peux pas le faire fonctionner, il y a quelque part, probablement, il me manque quelque chose.