En guise d'arrière-plan à cette question, je veux lier un "code fait" DataTable
à un . Pour conserver cette table, j'implémente l'interface ISerializable
. La table est affichée correctement, mais en postback pour trier les lignes, un InvalidCastExcpetion
est levé car les éléments de la ligne.ItemArray sont passés du type double
au type string
.DataTable sous-classé modifie les informations DataType de Double à Chaîne lors de la sérialisation/désérialisation
Ceci est la classe. Remarque: deux constructeurs, l'un pour la construction du DataTable initialement et un pour la construction de la table dans le processus de désérialisation:
[global::System.Serializable()]
[global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedTableSchema")]
public partial class HeatMapVisualisationDataTable : DataTable, System.Runtime.Serialization.ISerializable
{
#region members
public double _valueMin { get; private set; }
public double _valueMax { get; private set; }
#endregion membders
public HeatMapVisualisationDataTable(XemlExperimentHeatMapDataTable data)
: base("result", "http://gmd.mpimp-golm.mpg.de/HeatMap")
{
this.Columns.Add(new DataColumn("metabolite", typeof(Guid)));
this.Columns.Add(new DataColumn("name", typeof(string)));
DataColumn[] PrimaryKeyColumns = new DataColumn[1];
PrimaryKeyColumns[0] = this.Columns["metabolite"];
this.PrimaryKey = PrimaryKeyColumns;
SortedDictionary<int, DataColumn> headers = new SortedDictionary<int, DataColumn>();
foreach (var item in data.AsParallel().AsEnumerable().Select(x => x.ObservationPointId).Distinct().OrderBy(x => x))
{
DataColumn dc = this.Columns.Add(item.ToString(), typeof(Double));
headers.Add(item, dc);
}
foreach (var item in data)
{
DataRow tmpRow = base.Rows.Find(item.MetaboliteId);
if (tmpRow == null)
{
tmpRow = base.Rows.Add(new object[] { item.MetaboliteId });
tmpRow["name"] = item.MetaboliteName;
}
tmpRow[headers[item.ObservationPointId]] = item.value;
}
this.AcceptChanges();
_valueMax = data.AsParallel().AsUnordered().Max(x => x.value);
_valueMin = data.AsParallel().AsUnordered().Min(x => x.value);
}
public HeatMapVisualisationDataTable(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext ctxt) :
base(info, ctxt)
{
_valueMin = (double)info.GetValue("valueMin", typeof(double));
_valueMax = (double)info.GetValue("valueMax", typeof(double));
}
public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext ctxt)
{
base.GetObjectData(info, ctxt);
info.AddValue("valueMin", _valueMin);
info.AddValue("valueMax", _valueMax);
}
}
Comme je peux observer en lisant le schéma dans le SerializationInfo
dans le constructeur HeatMapVisualisationDataTable(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext ctxt)
, la table est correcte sérialisé et vient correctement du "magasin" en termes de schéma xml serilaised. Cependant, en regardant la classe de base construite dans ce constructeur, toutes les colonnes de type double
avant la sérialisation sont maintenant de type string
. Qu'est-ce que je fais mal?
Mise à jour 1: Je pourrais aussi reproduire ce problème en changeant le type de données numérique de double
à float
ou decimal
. La colonne de clé primaire de type Guid
est désérialisée dans le type correct.
Mise à jour 2: À mon avis, le comportement décrit est un suivi de certains problèmes DataTable.ReadXml()
où DataTypes de colonnes est remplacé par String.
Merci, Jan
Ma publication est liée à cette [question] (http://stackoverflow.com/questions/7041036/does-dataset-readxml-set-all-columns-datatype-in-its-table-as-string). Cependant, la réponse n'est pas applicable dans mon cas. – jahu
En outre, le code source fourni en bas de cette [page Méthode DataSet.ReadXml] (http://msdn.microsoft.com/en-us/library/d6swf149.aspx) assez bien illustre le problème: 'DataSet.ReadXml () 'définit toutes les colonnes du type de données dans la table comme' string', bien que déclaré différemment. Dans l'exemple MSDN donné, la colonne "id" est déclarée comme type "int" mais après avoir relu la table, la colonne est tapée comme "string". – jahu