0

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()_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.

Répondre

Questions connexes