Récupérer valeurs plusieurs tables d'un dataset

Résolu
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010 - 21 août 2010 à 18:39
 jdktdi - 3 déc. 2010 à 23:59
Bonjour à tous,

J'ai passé de longues heures à essayer de solutionner mon problèmes, et malgré toutes les recherches que j'ai effectuées, aucune ne m'a apporté la solution...

Je développe une application Windows Mobile 6 (Framework .NET 3.5), avec une base de données SQL Server CE.
Dans ma base de données, j'ai deux tables "clients" et "pays".
Chacune possédant une ID unique, et dont la table "clients" a une jointure de son champ "pays" pointant vers le "paysID" de la table "pays". Très classique.

J'utilise le concepteur de dataset qui me permet de créer visuellement tout cela.
J'ai donc rajouté deux tableadapters de ces bases de données et créé la jointure. Dans le tableadapter "clients" j'ai créé une requête select "FillBySearch" et "GetDataBySearch", dont la syntaxe est la suivante :
"SELECT clients.nom, clients.prenom, pays.nom FROM clients INNER JOIN pays ON clients.pays = pays.paysid"


Dans mon code, je veux mettre le résultat de cette requête dans une datatable :
'Création d'une instance de notre TableAdapter 'Clients' :
Dim ClientsTableAdapter As New datasetGestionClientsTableAdapters.clientsTableAdapter

'Création d'une instance de notre table associé :
Dim ClientsDataTable As New datasetGestionClients.clientsDataTable

'Appel de la méthode GetData de notre instance de TableAdapter pour le remplissage de la table :
ClientsDataTable = ClientsTableAdapter.GetDataBySearch()


Et là il me met une erreur :
"Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints."


J'ai bien essayé de mettre le 'EnforceConstraints' à False mais ca ne change rien...

PS : Cela fonctionne quand j'utilise uniquement une table...

Merci d'avance pour votre aide précieuse .

24 réponses

NSUADI Messages postés 540 Date d'inscription mardi 4 août 2009 Statut Membre Dernière intervention 1 février 2013 2
22 août 2010 à 18:01
donc avec ce code:
        Dim clientdttable As New forumDataSet.fk_tableDataTable 
        'clientdttable = clienttbadapt.GetData
        clientdttable = FkTableAdapter.GetDatanew
        Dim dv As New DataView(clientdttable)
        Fk_tableDataGridView.DataSource = dv


tu as à l'exécution ta datagridview qui repond parfaitement à ton soucis comme dans cette image sans les autres colonnes indésirables...
Ce qui compte,ce n'est pas ce qu'on a mais plutôt ce que l'on fait avec ce qu'on a...
Visual Basic .Net is the best and vb6.0
3
Mayzz Messages postés 2813 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 2 juin 2020 28
22 août 2010 à 19:01
Ah oui je comprend mieux maintenant !

@mcadaminc

Lors ce que tu crée un TableAdapter, celui-ci crée un modèle de DataTable depuis la requêtes SELECT.

Don si j'ai 'SELECT Nom, Prenom, Age FROM Users', le J'aurais dans mon DataSet le Schéma suivant :

Users
- Non
- Prenom
- Age
UsersTableAdapter
Fill, GetData

Par la suite, lors ce que j'appellerais Fill ou GetData d'UsersTableAdapter, il me retournera une table Users.

Donc c'est un modèle, tu ne peux pas mettre d'autres requêtes dans ce TableAdapter comme par exemple :

'SELECT Nom, Prenom, Age, Pays FROM Users'

Car la table qui sera retourné ne comporte pas de Champ 'Pays'. Comme te suggère NSUADI, crée un autre TableAdapter.
Un par modèle de table.

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
3
Mayzz Messages postés 2813 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 2 juin 2020 28
21 août 2010 à 20:51
Salut,

En fait, c'est qu'un des enregistrements de ta table clients ne possède pas de pays, ou un enregistrement d'ou l'erreur il me semble.

Une chose me chagrine :

Chacune possédant une ID unique, et dont la table "clients" a une jointure de son champ "pays" pointant vers le "paysID" de la table "pays".


J'ai donc rajouté deux tableadapters de ces bases de données et créé la jointure.


Normalement, lors ce que tu crée une jointure (Relation => Contrainte de clé étrangère) au sein de ta base, celle-ci est directement visible depuis ton Dataset fortement typé, tu n'as pas besoin de recréer cette relation, ça n'a pas été le cas pour toi ?

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
0
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010
21 août 2010 à 21:42
Merci pour votre réponse.

Ce n'est pas possible que ca soit à cause des données, j'ai testé en ayant qu'un seul enregistrement, en simplifié comme ceci :

Table Clients :
clientsid : 1
nom : Dupuis
prenom : Jean
pays : 1

Table Pays :
paysid : 1
nom : France

Je n'avais pas vu que dans ma base de données SQL Server CE (dans l'explorateur de serveur), en faisant un clic droit sur une table > Propriétés de la table, on savait rajouter une relation.
J'ai donc fait ainsi, en recommençant un nouveau projet. J'ai ensuite déplacé mes tables de l'explorateur de projet vers le dataset "visuel", et la jointure c'est en effet faite toute seule.

Maintenant, je recrée une requete (dans le dataset visuel : clic droit sur le tableadapter de la table "clients" > ajouter une requete. Dans l'assistant, je remet ma requête que j'ai indiquée au premier post. La requete est bien exécutée.

Je remet maintenant dans mon code le code indiqué au premier post, et toujours même erreur...
Il y a forcément moyen de récupérer les valeurs de plusieurs tables quand même ...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010
21 août 2010 à 21:58
Mdr, tu vas rire (pas moi en tout cas...), mais juste en redémarrant Visual Studio, ca a fonctionné....

Par contre, j'essaie de mettre le résultat dans un datagrid, mais j'ai un autre soucis :
'Création d'une instance de notre TableAdapter 'Clients' :
Dim ClientsTableAdapter As New datasetGestionClientsTableAdapters.clientsTableAdapter

'Création d'une instance de notre table associé :
Dim ClientsDataTable As New datasetGestionClients.clientsDataTable

'Appel de la méthode GetData de notre instance de TableAdapter pour le remplissage de la table :
ClientsDataTable = ClientsTableAdapter.GetDataBySearch()
Dim dv As New DataView(ClientsDataTable)
DataGrid1.DataSource = dv

Ca m'affiche bien les valeurs, par contre, dans ma requête j'ai demandé à n'avoir que "clients.nom, clients.prenom, pays.nom", et, en plus de ces 3 là, il m'affiche également les autres champs des deux tables !!! Une solution ?

Merci d'avance.
0
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010
21 août 2010 à 22:09
J'ai trouvé ici comment cacher des colonnes, c'est pas vraiment l'idéal car le mieux étant de vraiment avoir que les champs souhaités mais bon, si vous avez une solution...

http://faqvbnet.developpez.com/?page=form_dgrid#form_dgrid_mask_column

Merci pour ton aide Mayzz, grâce à toi j'ai réglé mon problème .
0
Mayzz Messages postés 2813 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 2 juin 2020 28
21 août 2010 à 22:30
Perso avec cette requête ça fonctionne chez moi :

SELECT        Clients.ClientID, Clients.Nom, Clients.Prenom, Pays.Nom AS Pays
FROM          Clients INNER JOIN Pays ON Clients.Pays = Pays.PaysID


Mais tu peux essayer la jointure de gauche

SELECT        Clients.ClientID, Clients.Nom, Clients.Prenom, Pays.Nom AS Pays
FROM          Clients LEFT OUTER JOIN Pays ON Clients.Pays = Pays.PaysID


Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
0
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010
21 août 2010 à 23:39
Merci,

Mais ce n'est pas un problème de requête. Elle fonctionne en effet.
Le truc c'est que quand je met le dataview dans le datagrid - si je puis dire -, il met met également tous les autres champs alors que j'en ai demandé que 3 dans ma requête...
0
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010
22 août 2010 à 01:27
Moarf, je vois qu'avec Visual Studio 2005 c'est pas possible de faire des relations entre les tables directement dans la base de donnée sql server 2005 mobile... Génial, retour à la case départ
0
Mayzz Messages postés 2813 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 2 juin 2020 28
22 août 2010 à 02:02
Ah oui, en SQL CE pas de serveur, c'est un composant, donc c'est très limité.

Mais t'es pas obligé d'ajouter une relation pour faire une requête sur deux tables. Les relations servent par exemple pour ma mise à jour des IDs ou la suppression, Ex:

Tu définis une contrainte de suppression en cascade et lors ce que tu supprimes un enregistrement de ta table 'Pays', celle-ci supprime automatiquement tous les Clients en rapport. Ce qui me parait logique au sein même d'un programme car si tu supprimes un pays c'est que tu ne veux plus des clients de ce pays. Cela évite aussi les erreurs de requêtes basées sur plusieurs tables.

Pour ton problème je ne vois pas, t'as du te planter quelque part dans la liaison de ton DataGridView.

Normalement, tu ouvres le smartTag puis tu choisi ta source de données, en suite ton DataSet fortement typé doit être disponible. Tu étends celui-ci et tu choisi ta DataTable, cette DataTable n'est pas celle de la base, non, mais celle qui correspond à la requête SELECT du TableAdapter associé, tu l'auras remarqué lors ce que tu crée un TableAdapter celui-ci attache un modèle de DataTable spécifique aux champs de ta requête (logique en cas de requête sur plusieurs tables).

Après avoir sélectionné ta table, le concepteur de vue te crée une instance de ton TableAdapter, de la DataTable associé, et un BindingSource lié à ta DataTable, c'est ce BindingSource qui est normalement lié à ton DataGridView, il sert à naviguer et à filtrer les champs.

Voila, normalement c'est ce que tu dois avoir à l'écran. Si t'as procédé autrement fais-moi le savoir et je tenterais de t'aider si je peux.

@+

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
0
NSUADI Messages postés 540 Date d'inscription mardi 4 août 2009 Statut Membre Dernière intervention 1 février 2013 2
22 août 2010 à 03:57
C'est quand même bizarre parce que lorsque tu exécutes la même requête dans le 'générateur de requêtes' cela fonctionne sans problème...
Ce qui compte,ce n'est pas ce qu'on a mais plutôt ce que l'on fait avec ce qu'on a...
Visual Basic .Net is the best and vb6.0
0
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010
22 août 2010 à 15:41
Merci pour vos réponses.

En fait, quand je met les objets bindingsource et tableadapters de ma table dans mon 'design' de ma form, que je ne précise pas de datasource au datagrid, et que je met dans le code :
Me.ClientstTableAdapter.FillBySearch(Me.DatasetGestionClients.clients)
DataGrid1.DataSource = ClientsBindingSource


Il me remplit comme souhaité le datagrid.
Donc cela fonctionne avec le "Fill" personnalisé, par contre cela ne fonctionne pas avec le "GetData" personnalisé... Et j'en ai grandement besoin pour faire d'autres requêtes comme celle que j'ai mise, mais avec une clause WHERE cette fois.
0
Mayzz Messages postés 2813 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 2 juin 2020 28
22 août 2010 à 16:00
Donc cela fonctionne avec le "Fill" personnalisé, par contre cela ne fonctionne pas avec le "GetData" personnalisé...


Attend je comprend plus rien là...

C'est quoi ton problème au juste ? Je croyais que c'était le fait d'avoir des colonnes en plus ? Ne mélange pas tout sinon on y comprendra plus rien et on ne pourra pas t'aider.

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
0
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010
22 août 2010 à 16:15
J'ai fait un rapide projet avec juste mon problème (bon les 2 tables ne sont pas les mêmes mais le principe reste identique), afin que vous jugiez concrètement de mon problème...

http://www.2shared.com/file/CNjUFF83/test2.html
(Voir : 'Save file to your PC: click here')

C'est vraiment quelque chose de tout simple à mes yeux, et j'y passe des heures, c'est incompréhensible...

Merci encore pour votre aide.

PS : Je viens de me rendre compte que c'est avec ton tutoriel, Mayzz, que j'ai appris .
0
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010
22 août 2010 à 16:18
@ Mayzz : Non, je croyait que cela était un soucis les colonnes en trop, mais cela n'est rien par rapport au problème principal.
Mon problème étant qu'il réussisse le Fill comme je l'ai expliqué, mais pas le GetData.
Désolé pour cette confusion, je me suis mal exprimé.
0
NSUADI Messages postés 540 Date d'inscription mardi 4 août 2009 Statut Membre Dernière intervention 1 février 2013 2
22 août 2010 à 16:34
avec ta solution,ça marche mais la datagridview affiche également les autres colonnes sans les données...c'est pas très académique.
Ce qui compte,ce n'est pas ce qu'on a mais plutôt ce que l'on fait avec ce qu'on a...
Visual Basic .Net is the best and vb6.0
0
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010
22 août 2010 à 16:38
@Nsuadi : En effet, en fait j'ai cru que ca marchait, mais c'était avec le Fill. Le GetData ne fonctionne pas. Milles excuses.
0
NSUADI Messages postés 540 Date d'inscription mardi 4 août 2009 Statut Membre Dernière intervention 1 février 2013 2
22 août 2010 à 17:35
la solution serait d'ajouter un nouveau tableadapter avec comme seule commande,la commande 'select'(donc:"SELECT Client.nom, Client.prenom, Pays.nom AS Expr1 FROM Client INNER JOIN Pays ON Client.pays = Pays.paysid") et ensuite travaller avec ce dernier pour remplir ta datagridview...
au cas où,j'ai pas été trop clair regarde cette image pour te faire une idée.

Ce qui compte,ce n'est pas ce qu'on a mais plutôt ce que l'on fait avec ce qu'on a...
Visual Basic .Net is the best and vb6.0
0
mcadaminc Messages postés 16 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 25 août 2010
23 août 2010 à 08:57
Bonjour,

Merci pour vos réponses .
Il semble qu'en effet cette méthode soit la bonne ! Je vais tester tout cela.
Par contre, il semblerait que si on met la requête dans le tableadapter d'une des tables, il faut absolument selectionner tous les champs de la tables (et non quelques uns comme j'ai fait) pour que cela fonctionne .
Mais bon ce n'est pas propre, contrairement à votre solution.

Je vous remercie tous les deux pour le temps que vous m'avez accordé .
0
Mayzz Messages postés 2813 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 2 juin 2020 28
23 août 2010 à 15:26
il semblerait que si on met la requête dans le tableadapter d'une des tables, il faut absolument selectionner tous les champs de la tables (et non quelques uns comme j'ai fait) pour que cela fonctionne


Non absolument pas, je vois que tu n'as pas compris, je vais essayer de t'expliquer un peu mieux

Dans ton exemple, tu as deux tables, dans la premières les champs 'id' clé primaire, 'iso', 'hdate' puis dans la seconde 'iso' clé primaire et 'ddebut'

Ta requête est formulée comme suit :

SELECT historique.hdate, equipement.ddebut ...


Donc la Table retournera bien ces deux champs, mais comme je te l'ai dis plus haut la table à été définie dans le equipementTableAdapter possède le schéma suivant :

iso
ddebut

Ces champs te seront donc retournés, c'est l'addition des champs de ta requête + des champs définis de la table qui donnent le tout :

iso
ddebut
hdate

Pour résumer, il ajoute le champ 'hdate' au schéma de la DataTable 'equipement'

Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer.
0
Rejoignez-nous