2008-10-19 3 views
9

Я новичок в мире ASP.NET и SQL сервера, поэтому простите пожалуйста мое невежество ...структура # Сохранение данных C в базу данных SQL

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

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

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

Спасибо!

ответ

22

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

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

Мнение: Я предпочитаю хранить сериализованные объекты как XML вместо двоичных данных. Почему? Поскольку вы действительно можете прочитать, что там (для отладки), а в SQL Server вы можете использовать XQuery для выбора данных из сериализованного объекта. По моему опыту, прирост производительности при использовании двоичных данных не стоит того, чтобы сравнивать данные, которые легче отлаживать, и их можно использовать в псевдо-реляционном режиме. Взгляните на SQL Server's XQuery capabilities. Даже если вы не планируете использовать его сразу, нет причин помещать себя в угол.

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

Я считаю, что вы называете вектор списком <> в C#. Взгляните в System.Collections.Generic. Вы можете использовать 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(); 
     } 
    } 
} 

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

Не забудьте указать System.Runtime.Serialization, чтобы получить доступ к NetDataContractSerializer.

2

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

+1

Итак, вы говорите, что если вам нужно сохранить что-то, что не является встроенным типом столбца базы данных, вместо этого вы должны использовать плоские файлы? – MusiGenesis 2008-10-20 00:28:04

+0

Почему бы не использовать базу данных? Это, безусловно, имеет преимущество в том, что оно более масштабируемо, чем плоский файл. И если вы используете формат сериализации XML, вы также можете запрашивать данные на SQL Server с помощью XQuery. – 2008-10-20 00:32:11

+0

Если вы сохраняете сложный объект в базе данных, каждое поле объекта должно получить собственный столбец или таблицу, чтобы вы могли искать и запрашивать в этом поле. – 2008-10-20 00:52:44

3

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

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

8
[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 
    } 
} 
2

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

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... 
0

у меня больше опыта работы с реляционными базами данных, чем C#, но двоичные сериализациями являются приемлемым способом пойти, так как это позволяет состоянию всего объекта, чтобы быть сохранены Int o база данных. Сериализация XML практически такая же, хотя общие типы не допускаются.

1

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

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

Смежные вопросы