Problème de sérialisation lors de l’utilisation de la méthode WriteXML

Ce que j’essaie de faire avec le code est d’exporter un jeu de données au format XML.

C’est ce que j’utilise actuellement:

dataSet.WriteXml(fileDialog.FileName, XmlWriteMode.WriteSchema); 

Mon dataset est un dataset typé correctement formé (par cela, je veux dire, toutes les tables ont une PK, et les relations FK sont définies entre toutes les tables existantes dans l’dataset). Certaines relations sont des relations nestedes. La table “TABLE” a deux FK et est en même temps parent de 8 autres tables.

Je reçois le message d’ erreur suivant: ” Impossible de procéder à la sérialisation de DataTable ‘TABLE’. Il contient un DataRow contenant plusieurs lignes parentes sur la même clé étrangère.

Quelqu’un peut-il me donner des indications sur ce que je fais mal? et pourquoi je reçois ce message d’erreur?

Merci d’avance.

Je sais qu’il est un peu tard, mais j’ai trouvé une solution de contournement.

J’ai rencontré le même problème en essayant de lire un schéma dans un jeu de données contenant les relations. L’erreur que vous obtiendrez dans ce cas est la suivante: ‘La même table’ {0} ‘ne peut pas être la table enfant de deux relations nestedes’ Je vais partager ce que j’ai appris

Le jeu de données fonctionne selon deux modes, bien que vous ne puissiez PAS le dire de l’extérieur.

  1. (a) Je suis un dataset ssortingct / créé manuellement, je n’aime pas les relations nestedes
  2. (b) Je suis un conteneur pour un object sérialisé, tout se passe.

Le jeu de données que vous avez créé est actuellement un “a”, nous voulons en faire un “b”. Le mode dans lequel il opère est décidé lorsqu’un jeu de données est “chargé” (xml) et / ou d’autres considérations.

Je passe des heures fébriles à lire le code du DataSet pour trouver un moyen de le tromper, et j’ai découvert que MS pouvait résoudre le problème en ajoutant simplement une propriété à l’dataset et en effectuant quelques vérifications supplémentaires. Vérifiez le code source de DataRelation: http://referencesource.microsoft.com/#System.Data/System/Data/DataRelation.cs,d2d504fafd36cd26, et que la seule méthode nécessaire pour tromper est la méthode ‘ValidateMultipleNestedRelations’. )

L’astuce consiste à tromper le jeu de données en lui faisant croire qu’il construit lui-même toutes les relations. La seule façon pour moi de faire cela est de faire en sorte que le jeu de données les crée, en utilisant la sérialisation.

(Nous utilisons cette solution dans la partie de notre système où nous créons une sortie avec un produit tiers orienté DataSet.)

En méta, ce que vous voulez faire est:

  1. Créez votre jeu de données dans le code, y compris les relations. Essayez si vous pouvez imiter la convention de dénomination MS (mais pas sûr si nécessaire)
  2. Sérialiser votre jeu de données (mieux vaut ne pas avoir de lignes)
  3. Faites en sorte que le jeu de données sérialisé ressemble à celui de MS. (Je vais développer sur ce ci-dessous)
  4. Lisez le jeu de données modifié dans une nouvelle instance.
  5. Maintenant, vous pouvez importer vos lignes, MS ne vérifie pas les relations et tout devrait fonctionner.

Certaines expériences m’ont appris que dans cette situation, moins, c’est plus. Si un dataset lit un schéma et ne détecte AUCUNE relation ou colonne-clé, il fonctionnera en mode “b”, sinon il fonctionnera en mode “a”. Il se pourrait que nous puissions toujours obtenir un dataset en mode «b» avec quelques relations ou colonnes-clés, mais cela n’était pas pertinent pour notre problème.

Donc, voilà, ce code suppose que vous avez une méthode d’extension ‘Serialize’ qui sait gérer un dataset.

Supposons que sourceDataSet est le DataSet avec le schéma uniquement. La cible sera l’dataset réellement utilisable:

 var sourceDataSet = new DataSet(); var source = sourceDataSet.Serialize(); // todo: create the structure of your dataset. var endTagKeyColumn = " msdata:AutoIncrement=\"true\" type=\"xs:int\" msdata:AllowDBNull=\"false\" use=\"prohibited\" /"; var endTagKeyColumnLength = endTagKeyColumn.Length - 1; var startTagConstraint = " 0) { // throw away unused key columns. while (source[subSsortingngEnd] != '<') subStringEnd--; if (subStringEnd - subStringStart > 5) { cleanedUp.Append(source.Subssortingng(subSsortingngStart, subSsortingngEnd - subSsortingngStart)); } subSsortingngStart = source.IndexOf('>', subSsortingngEnd + endTagKeyColumnLength) + 1; subSsortingngEnd = source.IndexOf(endTagKeyColumn, subSsortingngStart); } subSsortingngEnd = source.IndexOf(startTagConstraint, subSsortingngStart); while (subSsortingngEnd > 0) { // throw away relationships. if (subSsortingngEnd - subSsortingngStart > 5) { cleanedUp.Append(source.Subssortingng(subSsortingngStart, subSsortingngEnd - subSsortingngStart)); } subSsortingngStart = source.IndexOf(endTagConstraint, subSsortingngEnd) + endTagConstraintLength; subSsortingngEnd = source.IndexOf(startTagConstraint, subSsortingngStart); } cleanedUp.Append(source.Subssortingng(subSsortingngStart + 1)); target = new DataSet(); using (var reader = new SsortingngReader(cleanedUp.ToSsortingng())) { target.EnforceConstraints = false; target.ReadXml(reader, XmlReadMode.Auto); } 

Notez que, comme je l’ai dit au début, j’ai dû résoudre ce problème lorsque nous chargeons le jeu de données. Même si vous enregistrez le jeu de données, la solution de contournement sera la même.

Les deux clés étrangères sont à l’origine du problème. L’autre extrémité des clés est considérée comme un parent, vous en avez donc deux. En écrivant le XML, un élément ne peut avoir qu’un seul parent (à moins que l’élément n’apparaisse deux fois, une fois sous chaque parent). Parmi les solutions possibles, vous pouvez supprimer l’une des clés étrangères (ce qui, je EnforceConstraints , EnforceConstraints votre application), ou, en fonction de la manière dont votre dataset est initialisé, essayez de définir EnforceConstraints sur false .