web-dev-qa-db-fra.com

Puis-je enregistrer un «objet» dans une base de données SQL Server?

Je souhaite enregistrer un objet (de tout type) dans un champ d'une base de données dans SQL Server 2005. Est-ce possible? Dois-je convertir l'objet en quelque chose, comme un tableau d'octets par exemple et le restituer lors de sa récupération?

44
Ahmad Farid

Vous pouvez utiliser le type de champ VARBINARY(MAX) dans SQL Server, si vous le souhaitez. Vous pouvez y stocker tout type d'objet, jusqu'à 2 Go.

Pour y accéder, vous pouvez utiliser ADO.NET - quelque chose comme ceci:

object yourMysteryObject = (whatever you like it to be);

MemoryStream memStream = new MemoryStream();
StreamWriter sw = new StreamWriter(memStream);

sw.Write(yourMysteryObject);

SqlCommand sqlCmd = new SqlCommand("INSERT INTO TableName(VarBinaryColumn) VALUES (@VarBinary)", sqlConnection);

sqlCmd.Parameters.Add("@VarBinary", SqlDbType.VarBinary, Int32.MaxValue);

sqlCmd.Parameters["@VarBinary"].Value = memStream.GetBuffer();

sqlCmd.ExecuteNonQuery();

Marc

30
marc_s

J'utiliserais JSON pour convertir l'objet en chaîne et le stocker dans un champ VARCHAR ou TEXT. Non seulement les données sont stockées dans un format lisible par l'homme, mais elles sont également lisibles à partir de différentes langues, car presque toutes les langues traditionnelles disposent d'un analyseur JSON.

Le lien que j'ai posté contient des liens vers plusieurs bibliothèques dans de nombreuses langues (y compris C #), j'ai utilisé celui-ci plusieurs fois dans le passé.

23
Badaro

Comme d'autres l'ont dit, la sérialisation peut être la clé ici (en supposant que vous ne voulez pas utiliser ORM pour stocker les propriétés sous forme de colonnes dans une table, ce qui semble beaucoup plus direct).

Quelques mises en garde cependant; une base de données est:

  • stockage à long terme
  • pas lié à votre code .NET

En tant que tel, vous ne souhaitez pas utiliser une technique de sérialisation spécifique à la plate-forme ou à la version. Vous verrez souvent des gens mentionner BinaryFormatter pour la persistance, mais cela tombe dans les deux pièges ci-dessus. Vous seriez saboté si vous changiez de plate-forme, ou même si vous juste changez certaines propriétés .

Vous avez besoin d'une approche indépendante de l'implémentation; le plus simple (qui conserve également la capacité d'être lisible par l'homme) est xml ou json, peut-être via XmlSerializer ou Json.NET (stocké dans une [n]varchar(max)). Si vous ne vous souciez pas de la lisibilité humaine, les "tampons de protocole" (rapide/binaire) feraient bien (stockés dans une varbinary(max)), et sont disponibles pour la plupart des plateformes (y compris C # /. NET/etc).

12
Marc Gravell

Voici un exemple si vous utilisez Entity Framework (EF):

using (DbContext db = new DbContext())
{
    // The object that you want to serialize. In this case it is just an empty instance
    YourObject objectToSerialize = new YourObject();
    IFormatter formatter = new BinaryFormatter();
    using (MemoryStream stream = new MemoryStream())
    {
        formatter.Serialize(stream, objectToSerialize);

        // EF model. In one of its properties you store the serialized object
        YourModel modelObject = new YourModel();

        // In your model 'SerializedObject' should be of type byte[]. In the database it should be of type varbinary(MAX)
        modelObject.SerializedObject = stream.ToArray(); 
        db.YourModel.Add(modelObject);
        db.SaveChanges();
    }
}

Et voici comment dé-sérialiser l'objet:

// De-serialize
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream(serializedObject);
YourObject deserializedYourObject = (YourObject)formatter.Deserialize(stream);
stream.Close();
11
Ivo Stoyanov

Pour ce faire, vous devez sérialiser votre objet. Vous pouvez voir ici des exemples:

http://www.c-sharpcorner.com/UploadFile/bipinjoshi/serializingObjectsinCS11102005234746PM/serializingObjectsinCS.aspx

1
Thinker