2009-07-31 9 views
18

Quelqu'un peut-il suggérer le meilleur moyen de sérialiser des données (une classe en fait) à une base de données? J'utilise SQL Server 2008 mais je suppose que je dois sérialiser la classe à une chaîne/ou un autre type de données avant de stocker dans la base de données?Sérialiser la classe C# directement sur le serveur SQL?

Je suppose que ce champ doit être texte ou binaire? Est-ce que SQL Server 2008 (ou .net 3.5) prend en charge la sérialisation directement dans la base de données?

Toute aide vraiment apprécié

Répondre

36

Vous pouvez xml sérialiser la classe dans un champ xml. Nous l'utilisons tout le temps pour la journalisation des exceptions dans un ETL.

Utilisation du XmlSerializer vous voudrez peut-une méthode d'aide quelque part qui sérialise la classe à une chaîne ...

public static string SerializeToXml<T>(T value) 
{ 
    StringWriter writer = new StringWriter(CultureInfo.InvariantCulture); 
    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    serializer.Serialize(writer, value); 
    return writer.ToString(); 
} 

Ensuite vient de mettre la chaîne dans la db comme les autres.

+0

Pourquoi je ne pensais pas à l'aide d'un générique pour cela? * face palm * –

+2

@tom - parce qu'il n'y a pas besoin d'un générique ici. Vous pouvez également utiliser "valeur d'objet", puis appeler "value.GetType()" lors de la construction du sérialiseur. –

+0

Merci J'ai finalement fait, travaille un traitement –

19

Le meilleur meilleur moyen de stocker des données dans une base de données est dans les colonnes (par propriété), de sorte qu'il est interrogeable et indexable. Les outils ORM vont vous aider.

Cependant, il est également possible de sérialiser une classe en tant que CLOB/blob (varchar(max)/varbinary(max) etc).

C'est ce que vous voulez, évitez tout ce qui est spécifique à l'implémentation ou à la version; donc en particulier, ne pas utiliser BinaryFormatter. Tout ce qui est basé sur un contrat devrait fonctionner; XmlSerializer, DataContractSerializer, etc. Ou pour binaire rapide, protobuf-net pourrait valoir le détour.

Mais je souligne; les colonnes seraient mieux.

+0

marc - pourquoi vous conseille tyo éviter BinaryFormatter? c'est la moins grande taille ... De plus, comment Contract base améliore-t-il les données sauvegardées dans db? –

+0

@RoyiNamir il peut avoir de graves problèmes avec le versionnement, en raison de l'inclusion des noms de type complet (y compris les assemblages) etc, et étant dépendant du champ. Ce n'est pas non plus le plus petit par un tir de longue durée. Je conseillerais habituellement protobuf-net qui est généralement moins d'espace * et * évite tous les problèmes de versioing - mais je suis un peu biaisé. –

+0

je vois, mais ne comprends toujours pas le «en raison de l'inclusion des noms de type complet» .. Qu'est-ce qui ne va pas avec ça? ce qui est faux si im stocker le type (exemple: 'Liste ()') ... pouvez-vous s'il vous plaît expliquer dans un mot ou 2? Merci. –

1

J'ai numéroté des objets en XML et les ai jetés dans la base de données. Comme nous connaissions la quantité maximale de texte, nous utilisions le type de données varchar (max) au lieu d'entrer dans les formats TEXT ou Binary.

Il s'agissait d'une application Web OLTP et une chose que nous avons trouvée était que l'utilisation d'une colonne avec un type de données xml invoquait une utilisation importante de cpu lorsque le xml était validé à chaque insertion. Dans notre cas, le fichier XML n'a jamais été interrogé pour quoi que ce soit, donc ne pas avoir les capacités de requête XML a bien fonctionné pour nous.

0

Il y a deux options:

sérialisation Runtime, les objets sérialisables sont marqués avec l'attribut Serializable , auquel cas la classe IFormatter fait tout le travail de sérialisation. Un objet sérialisable peut ISerializable, mais vous devrez ensuite implémenter la méthode GetObjectData(). Le problème avec la sérialisation d'exécution est que le programme lisant les données xml doit avoir la connaissance des types CLR.

Sérialisation Xml: Sérialisation runtime Unline, vous obtiendrez une bonne interopérabilité dans ce cas. Le type XmlSerializer contient les méthodes Serialize() et Deserialize(), donc n'importe quel objet peut être sérialisé en XML et enregistré dans la base de données et quand vous le récupérez, vous pouvez le désérialiser facilement.

Pour lire les données de la base de données, vous pouvez utiliser la méthode SqlCommand class qui exécute des requêtes SQL, à savoir ExecuteXmlReader(). ExecuteXmlReader() renvoie une instance de XmlReader et qui lira vos données XML.

3

Sans génériques (meilleure sollution)

public static string SerializeToXml(object value) 
{ 
    StringWriter writer = new StringWriter(CultureInfo.InvariantCulture); 
    XmlSerializer serializer = new XmlSerializer(value.GetType()); 
    serializer.Serialize(writer, value); 
    return writer.ToString(); 
} 
Questions connexes