Хранение структуры данных C# в базе данных SQL



Я новичок в мире ASP.NET и SQL server, так что прошу простить мое невежество ...



Если у меня есть структура данных в C# (например, скажем, вектор, который хранит некоторые строки), можно ли хранить содержимое вектора, как в SQL-таблице? Я хочу сделать это так, чтобы он быстро преобразовал эти данные обратно в векторную форму как можно быстрее, не создавая его элемент за элементом. Почти как запись двоичных данных в файл, а затем чтение и копирование в него. выделенная структура в с.



Я создал таблицу на SQL Server 2008, для которой поле определено как VARBINARY (MAX). Я думал, что начну с этого.



Может ли кто-нибудь показать мне пример того, как я буду хранить и извлекать вектор, скажем, из 10 строк, в это поле и из него? Возможно ли это вообще (я не могу придумать, почему бы и нет)?



Спасибо!

844   7  

7 ответов:

Во-первых, существует очевидный путь простого создания реляционной структуры и сопоставления объекта с полями в базе данных.

Во-вторых, если у вас есть сериализуемый объект, вы можете сохранить его в SQL server. Я делал это время от времени и использовал текстовый тип данных в SQL Server для хранения XML.

мнение: я предпочитаю хранить сериализованные объекты в виде XML, а не двоичных данных. но почему? Потому что вы действительно можете прочитать, что там (для отладка), а в SQL Server можно использовать XQuery для выбора данных из сериализованного объекта. По моему опыту, выигрыш в производительности от использования двоичных данных не стоит того, чтобы сравнивать его с данными, которые легче отлаживать и которые можно использовать в режиме psuedo-relational. Взгляните на возможности XQuerySQL Server . Даже если вы не планируете использовать его сразу, нет причин ставить себя в угол.

Вы можете посмотреть на некоторые примеры, используя NetDataContractSerializer .

Я полагаю, что то, что вы называете вектором, является списком в C#. Загляните в систему.Коллекции.Родовой. Вы можете использовать NetDataContractSerializer для сериализации списка из 3 строк, таких как:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.IO;

namespace SerializeThingy
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> myList = new List<string>();
            myList.Add("One");
            myList.Add("Two");
            myList.Add("Three");
            NetDataContractSerializer serializer = new NetDataContractSerializer();
            MemoryStream stream = new MemoryStream();
            serializer.Serialize(stream, myList);
            stream.Position = 0;
            Console.WriteLine(ASCIIEncoding.ASCII.GetString(stream.ToArray()));
            List<string> myList2 = (List<string>)serializer.Deserialize(stream);
            Console.WriteLine(myList2[0]);
            Console.ReadKey();
        }
    }
}

Этот пример просто сериализует список, выводит сериализацию на консоль, а затем доказывает, что она была правильно гидратирована на обратной стороне. Я думаю, вы можете увидеть, что отсюда вы можете либо сбросить поток памяти в строку и записать его в база данных, или использовать другой тип потока, чем поток памяти, чтобы сделать это.

Помните о системе отсчета.Во время выполнения.Сериализация для получения доступа к NetDataContractSerializer.

[Serializable]
public struct Vector3
{
    public double x, y, z;
}

class Program
{
    static void Main(string[] args)
    {
        Vector3 vector = new Vector3();
        vector.x = 1;
        vector.y = 2;
        vector.z = 3;

        MemoryStream memoryStream = new MemoryStream();
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(memoryStream, vector);
        string str = System.Convert.ToBase64String(memoryStream.ToArray());

        //Store str into the database
    }
}

Предполагая, что объекты помечены [Serializable] или реализуют ISerializable класс the BinaryFormatter дает простой способ сделать это.

Если нет, то вы смотрите на (нетривиальный) пользовательский код.

Если вы собираетесь сделать это (и я думаю, что технически это возможно ), Вы можете также использовать плоский файл: нет смысла больше использовать реляционную базу данных.

Вот еще один более общий подход к общим спискам. Обратите внимание, что фактический тип, хранящийся в списке, также должен быть сериализуемым

using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Data.SqlClient;
using System.Runtime.Serialization;

public byte[] SerializeList<T>(List<T> list)
{

    MemoryStream ms = new MemoryStream();

    BinaryFormatter bf = new BinaryFormatter();

    bf.Serialize(ms, list);

    ms.Position = 0;

    byte[] serializedList = new byte[ms.Length];

    ms.Read(serializedList, 0, (int)ms.Length);

    ms.Close();

    return serializedList; 

} 

public List<T> DeserializeList<T>(byte[] data)
{
    try
    {
        MemoryStream ms = new MemoryStream();

        ms.Write(data, 0, data.Length);

        ms.Position = 0;

        BinaryFormatter bf = new BinaryFormatter();

        List<T> list = bf.Deserialize(ms) as List<T>;

        return list;
    }
    catch (SerializationException ex)
    {
        // Handle deserialization problems here.
        Debug.WriteLine(ex.ToString());

        return null;
    }

}

Затем в коде клиента:

List<string> stringList = new List<string>() { "January", "February", "March" };

byte[] data = SerializeList<string>(stringList);

Одним из основных способов хранения / извлечения этого массива байтов может быть использование простых объектов SQLClient:

SqlParameter param = new SqlParameter("columnName", SqlDbType.Binary, data.Length);
param.Value = data; 

etc...

Есть причины быть гибким. Правила, или руководящие принципы, для структуры базы данных не должны препятствовать творчеству. Учитывая первый поток здесь, я вижу гибридный подход для хранения как сериализованных, так и ограничивающих столбцов. Многие приложения могут быть значительно улучшены, если держать свой ум открытым для возможностей.

В любом случае, я оценил точку зрения новичков на этот вопрос. Держит нас все свежее..

У меня больше опыта работы с реляционными базами данных, чем с#, но двоичная сериализация является приемлемым способом, так как она позволяет сохранять все состояние объекта в базе данных. XML-сериализация почти такая же, хотя универсальные типы не допускаются.

Comments

    Ничего не найдено.