Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2453 connectés 

  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  Problème MySqlParameter c#

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème MySqlParameter c#

n°1806256
silvinus
Posté le 30-10-2008 à 11:22:48  profilanswer
 

Bonjour,
 
Voila j'ai crée une classe généric appelé Object qui est censé pouvoir charger/sauvegarder/modifier n'importe lequel de mes objets metiers.
Chaqu'un de mes objets metiers sont hérité d'une classe générique appelé Table, ils possède en plus un attribut qui définit le nom de la table et la clé primaire de la table en base. Chacune des propriétés possèdent un attribut correspodant au nom et au type du champ en base.
Ca c'est pour le contexte. Mon problème se situe au niveau de la sauvegarde. A chaque fois que je veux sauvegarder un object, je boucle sur les attribut et je récupère le nom du champs et la valeur associé, je construit ma requête comme ca.
La structure de la requête est correct mais les valuers ne sont pas remplacé. Par exemple pour une requête du type insert il me mettra :  
INSERT INTO test (id, value) values (@ID, @value). Il ne remplace pas les identifiants des paramètres par leurs valeurs.
Voici mon code, j'éspère avoir été assez clair :
 
 public static void SaveObject(AGDDataTable poObject)
        {
            MySqlConnection cn;
            MySqlParameter param;
            MySqlCommand cmd;
            String sSqlUpdate;
            String sSqlInsertFields;
            String sSqlInsertValues;
 
            Type type = poObject.GetType();
 
            AGDTable atrTable = ((AGDTable[])type.GetCustomAttributes(typeof(AGDTable), true))[0];
            String sTableName = atrTable.TableName;
            String sPrimaryKey = atrTable.PrimaryKey;
            String sVirgule = "";
 
            sSqlUpdate = "UPDATE " + sTableName + " SET ";
 
            sSqlInsertFields = "INSERT INTO " + sTableName + "(" + sPrimaryKey;
            sSqlInsertValues = " VALUES(@ID";
 
            foreach (PropertyInfo pi in type.GetProperties())//Construction de la requête à partir des propriétés de ma classe
            {
                AGDField[] aoField = (AGDField[])pi.GetCustomAttributes(typeof(AGDField), false);
                if (aoField.Length > 0)
                {
                    String sFieldName = aoField[0].FieldName;
 
                    sSqlUpdate += sVirgule + sFieldName + " = @" + sFieldName;
                    sSqlInsertFields += ", " + sFieldName;
                    sSqlInsertValues += ", @" + sFieldName;
 
                    sVirgule = ", ";
                }
            }
 
            sSqlUpdate += " WHERE " + sPrimaryKey + " = @ID";
            sSqlInsertFields += " )";
            sSqlInsertValues += " )";
 
            cn = new MySqlConnection(Properties.Resources.SECUConnectionString);
            cn.Open();
 
            if (poObject.Id > 0)
            {
                cmd = new MySqlCommand(sSqlUpdate, cn);
            }
            else
            {
                poObject.Id = GetNextId(sTableName);
 
                cmd = new MySqlCommand(sSqlInsertFields + sSqlInsertValues, cn);
            }
 
            foreach (PropertyInfo pi in type.GetProperties())//Création des parametres  
            {
                AGDField[] aoField = (AGDField[])pi.GetCustomAttributes(typeof(AGDField), false);
                if (aoField.Length > 0)
                {
                    //Récupère l'attribut AGDField permettant de savoir le nom du champ et le type en base
                    AGDField field = aoField[0];
                    param = new MySqlParameter(field.FieldName, field.DBType);
 
                    //Récupère la valeur de cette propriété pour cette instance d'objet
                    param.Value = pi.GetValue(poObject, null);
                    cmd.Parameters.Add(param);
                }
            }
 
            param = new MySqlParameter(sPrimaryKey, MySqlDbType.Int64);
            param.Value = poObject.Id;
            cmd.Parameters.Add(param);
 
            try
            {
                cmd.ExecuteNonQuery();
            }
            catch (Exception excp)
            {
                Exception myExcp = new Exception("Could not Save " + poObject.GetType().Name + ". Error: " +
                    excp.Message, excp);
                throw (myExcp);
            }
 
        }
 
Voila si quelqu'un sait pourquoi mes paramètres sont mal pris en compte je suis tout ouie :)

mood
Publicité
Posté le 30-10-2008 à 11:22:48  profilanswer
 

n°1806267
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 30-10-2008 à 11:35:29  profilanswer
 

tu fais un peu n'importe quoi toi hein... [:shakalagoons]

 

1) créer une classe qui s'appelle Object c'est dangereux, car il existe déjà une classe Object dans l'arborescence de classes .NET, dont héritent toutes les classes

 

2) pour tes paramètres pas pris en compte, je sais pas ce que t'essaies de faire avec tes concaténations de chaines là, mais ça rime à rien. pourquoi ne pas faire un truc genre

Code :
  1. String req= "INSERT INTO Table(champ1, champ2) VALUES(?field1, ?field2);
  2. MySqlCommand cmd = new MySqlCommand(connection, req);
  3. cmd.Parameters.Add("?field1", valeur);
  4. cmd.Parameters.Add("?field2", valeur);
  5. cmd.ExecuteNonQuery();
  6. ...


au lieu de ton foreach bien cracra ?


Message édité par Harkonnen le 30-10-2008 à 11:36:50

---------------
J'ai un string dans l'array (Paris Hilton)
n°1806272
silvinus
Posté le 30-10-2008 à 11:41:43  profilanswer
 

Pour la premiere remarque, elle ne s'appelle pas Object tout cours mal DALObject, j'ai dit object pour montrer qu'elle était générique (dsl de l'ambiguité).
Ensuite je ne connais ni les champs ni les valeurs lorsque j'appelle cette fonction.
Elle recoit un object de type AGDDataTable qui peut représenter n'importe qu'elle classe metier de mon application.
D'ou l'utilité de ma boucle foreach qui me sert à récupérer les champs et les valeurs je te mets en exemple une d mes classes metiers :
[AGDTable("SESSION", "ID_SESSION" )]
    public class Session : AGDDataTable
    {
        [AGDField("ID_LOGIN", AGDDBType.BigInt, typeof(Login))]
        public Login Login { get; set; }
 
        [AGDField("ID_BD", AGDDBType.BigInt, typeof(BD))]
        public BD BD { get; set; }
 
        [AGDField("DATEHDEBUT_SESSION", AGDDBType.BigInt)]
        public Int64 DateDebut { get; set; }
 
        [AGDField("DATEHFIN_SESSION", AGDDBType.BigInt)]
        public Int64 DateFin { get; set; }
 
        [AGDField("IP_SESSION", AGDDBType.Char)]
        public String Ip { get; set; }
 
        [AGDField("DTAEHMANIF_SESSION", AGDDBType.BigInt)]
        public Int64 DateManif { get; set; }
 
        [AGDField("ID_DATETRAITEMENT", AGDDBType.BigInt)]
        public Int64 DateTraitement { get; set; }
         
        [AGDField("CONTEXT_SESSION", AGDDBType.Blob)]
        public String Context { get; set; }
    }
Comme tu peux le voir la classe comme les propriétés ont un attribut, qui me permet de faire la liaison avec la table en base.
 
Tu vois ce que j'éssai de faire ou je suis vrement pas clair?

n°1806420
silvinus
Posté le 30-10-2008 à 15:55:05  profilanswer
 

Personne n'a une petite idée?

n°1806444
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 30-10-2008 à 16:24:59  profilanswer
 

tu utilises un ORM ?


---------------
J'ai un string dans l'array (Paris Hilton)
n°1806447
silvinus
Posté le 30-10-2008 à 16:31:31  profilanswer
 

Non je n'utilise pas d'ORM.
Tu penses que ce serait plus simple?

n°1806450
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 30-10-2008 à 16:34:15  profilanswer
 

Non mais je me demandais la provenance des metadata en entête de tes méthodes...


---------------
J'ai un string dans l'array (Paris Hilton)
n°1806459
silvinus
Posté le 30-10-2008 à 16:37:47  profilanswer
 

Ah,  ce sont des classes généric que j'ai crée.
En fait leur but est de faire une sorte de correspondance entre mes objets metiers et ma base de données

n°1806466
silvinus
Posté le 30-10-2008 à 16:43:02  profilanswer
 

En fait j'ai un peu plus approfondie mes recherches sur mon bug.
Il s'avère que ma requête se génère correctement, mes paramètre aussi.
Le pire c'est que en mode pas à pas une requète de mise à jours s'éxécute bien! Mais elle ne met pas a jour mon info! Malgré le fait que mon objet ai été modifié.
C'est la que je comprend plus
Mes paramètres contiennent bien les données modifié, ma requète s'éxécute mais pas de changement en base! tu vois?

n°1806934
moi23372
Posté le 31-10-2008 à 13:58:53  profilanswer
 

un commit manquant peut être?


---------------
quand un homme raisonne mal c'est qu'il n'a pas les données pour raisonner mieux (diderot)
mood
Publicité
Posté le 31-10-2008 à 13:58:53  profilanswer
 

n°1807583
silvinus
Posté le 03-11-2008 à 08:55:54  profilanswer
 

La methode executenonQuery a besoin d'un commit?
Je me renseigne

n°1807584
silvinus
Posté le 03-11-2008 à 09:02:28  profilanswer
 

Non j'ai tenter de le faire en transactionnel ca marche pas mieux.
 
Je suis en pleine déprime :)

n°1807621
silvinus
Posté le 03-11-2008 à 11:28:17  profilanswer
 

Ok c'est bon,
en fait à l'initialisation de mes paramètres, le constructeur de MySqlParameter ne comprenait pas que field.DBType était le type de mon champ il considérait que c'était sa valeur.
J'ai retranscrit mon DBType en MySqlDBType et ca marche.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  Problème MySqlParameter c#

 

Sujets relatifs
ACTIONSCRIPT : Problème bouton/récupération champ texte[résolu] Problème d'accent avec FOP
[Résolu] - [Batch Dos] Probleme carateres dans resultat txtProblème avec INSTR
Problème objet avec PHPProblème wordpress
Probleme de requête SQL avec Windev trier par dateProblème de Random pour Dichotomie
Problème MCDptit probleme pour afficher du contenu sql en PHP
Plus de sujets relatifs à : Problème MySqlParameter c#


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR