2009-07-31 12 views
18

qualcuno può suggerire il modo migliore per serializzare i dati (una classe in realtà) in un DB?Serializzare la classe C# direttamente sul server SQL?

Sto utilizzando SQL Server 2008 ma presumo di dover serializzare la classe su una stringa o su un altro tipo di dati prima di archiviarlo nel database?

Suppongo che questo campo debba essere testo o binario ??

SQL Server 2008 (o .net 3.5) supporta la serializzazione direttamente nel database ??

Qualsiasi aiuto molto apprezzato

risposta

36

È possibile xml serializzare la classe in un campo XML. Lo usiamo sempre per la registrazione delle eccezioni in un ETL.

Utilizzando il XmlSerializer si può decidere un metodo di supporto da qualche parte, che serializza la classe in una stringa ...

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(); 
} 

Poi basta inserire la stringa nel db come qualsiasi altro.

+0

Perché non pensare di utilizzare un generico per questo? * faccia palm * –

+2

@ tom - perché non c'è bisogno di un generico qui. Potresti ugualmente usare "valore oggetto" e quindi chiamare "value.GetType()" quando costruisci il serializzatore. –

+0

Grazie, finalmente l'ho fatto, funziona a meraviglia –

19

Il modo migliore per memorizzare i dati in un database è in colonne (per struttura), in modo che sia interrogabile e indicizzabile. Gli strumenti ORM ti aiuteranno in questo.

Tuttavia, è anche possibile serializzare una classe come un CLOB/BLOB (varchar(max)/varbinary(max) etc).

Questo è ciò che si desidera, evitare qualsiasi implementazione specifica o versione intollerante; quindi, in particolare, non utilizzare BinaryFormatter. Qualsiasi cosa basata sul contratto dovrebbe funzionare; XmlSerializer, DataContractSerializer, ecc. Oppure per il binario veloce, vale la pena dare un'occhiata a protobuf-net.

Ma sottolineo; le colonne sarebbero migliori

+0

marc - perché si consiglia di evitare BinaryFormatter? è di dimensioni inferiori ... Inoltre, in che modo Contract base migliora i dati salvati in db? –

+0

@RoyiNamir può avere seri problemi con il controllo delle versioni, a causa dell'inserimento di nomi di tipi completi (inclusi gli assembly) ecc. E della dipendenza dal campo. Inoltre non è il più piccolo di un tiro lungo. Di solito consiglierei protobuf-net che di solito è meno spazio * e * evita tutti i problemi di versioing - ma sono un po 'di parte. –

+0

vedo, ma ancora non capisco il 'dovuto includere i nomi dei tipi completi '.. Cosa c'è di sbagliato in questo? cosa è sbagliato se sto memorizzando il tipo (esempio: 'Lista ()') ... puoi spiegare in una parola o 2? Grazie. –

1

Ho serializzato gli oggetti come XML e li ho buttati nel database bene. Dato che conoscevamo la quantità massima di testo, abbiamo usato il tipo di dati varchar (max) invece di entrare nei formati TEXT o Binario.

Questa era un'applicazione Web OLTP e una cosa che abbiamo scoperto è che l'utilizzo di una colonna con un tipo di dati xml ha richiamato un uso significativo della CPU poiché l'xml è stato convalidato su ogni inserto. Nel nostro caso l'xml non è mai stato interrogato per qualcosa, quindi non avere le capacità di interrogazione xml ha funzionato bene per noi.

0

Ci sono un paio di opzioni:

Runtime serializzazione, oggetti serializzabili sono contrassegnati con l'attributo Serializable , nel qual caso la classe IFormatter fa tutto il lavoro di serializzazione. Un oggetto serializzabile può essere ISerializable, ma in tal caso sarà necessario implementare il metodo GetObjectData(). Il problema con la serializzazione di runtime è che il programma che legge i dati xml deve avere la conoscenza dei tipi CLR.

Serializzazione Xml: serializzazione runtime non allineata, si otterrà una buona interoperabilità in questo caso. Il tipo XmlSerializer contiene i metodi Serialize() e Deserialize(), quindi qualsiasi oggetto può essere serializzato in XML e salvato nel database e quando lo si recupera, è possibile deserializzare lo .

Per leggere i dati dal database, è possibile utilizzare il metodo SqlCommand che esegue query SQL, ovvero ExecuteXmlReader(). ExecuteXmlReader() restituisce un'istanza di XmlReader e leggerà i dati xml.

3

Senza generici (meglio 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(); 
} 
Problemi correlati