Bonjour,
Je suis en plein System.Reflection avec le Compact Framework 2.0 pour Windows mobile 6.5.3.
Je cherche à extraire des données d'une base de données de façon générique car il y a plusieurs tables. L'objet MaClasse est intouchable car généré automatiquement et partager avec l'application sur le PC pour la génération de fichiers XML dans les 2 sens.
En entrée, il y a la liste des champs que je souhaite sortir (strFields), l'objet destination (objTable) et les conditions à respecter (strCondition).
En sortie, MaClasse est rempli sans que j'ai à me soucier des champs.
Mon besoin :
A la dernière ligne (en gras), j'ai le message d'erreur suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 static class Program { static void Main() { MaClasseHerite mcl = new MaClasseHerite(); mcl.ExportQuery("Champ1,Champ2", new MonObjet1(), "Champ2 = 'Test'"); mcl.ExportQuery("Champ3,Champ4,Champ5", new MonObjet2(), "Champ5 = 'Extraire'"); } } // Intouchable car autogénéré public partial class MaClasse { private _MaArray1[] MonObjet1; private _MaArray2[] MonObjet2; // et les accesseurs get/set classiques; } public class MaClasseHerite : MaClasse { public void ExportQuery(string strFields, object objTable, string strCondition) { // Le nom de l'objet correspond au nom de ma table à "T_" prêt dans la requête string strTableName = objTable.GetType().Name; // Récupérer les données dans une DataTable DataTable dtb = clsDB.SqlRequest("SELECT " + strFields + " FROM T_" + strTableName + (strCondition.Length > 0 ? " WHERE " + strCondition : string.Empty)); List<object> cmbList = new List<object>(); foreach (DataRow drw in dtb.Rows) { object obj = Activator.CreateInstance(objTable.GetType()); foreach (DataColumn dcl in dtb.Columns) foreach (PropertyInfo ppy in obj.GetType().GetProperties()) if (ppy.Name == dcl.ColumnName) ppy.SetValue(obj, drw[dcl], null); cmbList.Add(obj); } if (dtb.Rows.Count > 0) foreach (PropertyInfo ppy in this.GetType().GetProperties()) if (ppy.Name == strTableName) ppy.SetValue(this, cmbList.ToArray(), null); } }
ArgumentException
à System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean verifyAccess, StackCrawlMark& stackMark)
à System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
à System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
à System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
à MyNameSpace.Model.MaClasseHerite.ExportQuery(String strFields, Object objTable, String strCondition)
à MyNameSpace.Program.Main()
Mon collègue me dit de faire comme ça :
Bien sûr, vous l'aurez compris, il n'y a pas que 2 MaArray mais beaucoup plus. De plus, si je dois sortir un champ en plus, je dois programmer, alors qu'avec la méthode visée, je peux avoir cela dans un app.config.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 static class Program { static void Main() { MaClasse mcl = new MaClasse(); // Récupérer les données dans une DataTable DataTable dtb = clsDB.SqlRequest("SELECT Champ1,Champ2" + " FROM T_MaArray1" + " WHERE Champ2 = 'Test'"); List<MonObjet1> cmbList = new List<MonObjet1>(); foreach (DataRow drw in dtb.Rows) foreach (DataColumn dcl in dtb.Columns) { MonObjet1 cbm = new MonObjet1(); cbm.Champ1 = int.Parse(drw[0].ToString()); cbm.Champ2 = drw[1].ToString(); cmbList.Add(cbm); } mcl.MaArray1 = cmbList.ToArray(); // Récupérer les données dans une DataTable DataTable dtb = clsDB.SqlRequest("SELECT Champ3,Champ4,Champ5" + " FROM T_MaArray2" + " WHERE Champ5 = 'Extraire'"); List<MonObjet2> cmbList = new List<MonObjet2>(); foreach (DataRow drw in dtb.Rows) foreach (DataColumn dcl in dtb.Columns) { MonObjet2 cbm = new MonObjet2(); cbm.Champ3 = int.Parse(drw[0].ToString()); cbm.Champ4 = drw[1].ToString(); cbm.Champ5 = drw[2].ToString(); cmbList.Add(cbm); } mcl.MaArray2 = cmbList.ToArray(); } } // Intouchable car autogénéré public partial class MaClasse { private _MaArray1[] MonObjet1; private _MaArray2[] MonObjet2; // et les accesseurs get/set classiques; }
Merci d'avance de m'avoir lu, j'espère m'être fait comprendre correctement sur mon besoin et surtout je suis tout ouïe de vos idées.
Edit : Erreur de transcription du code dans le Main de la demande.
Partager