registros - Almacenamiento de la estructura de datos C#en una base de datos SQL
modificar insertar eliminar buscar datagridview en c# (7)
Soy nuevo en el mundo de los servidores ASP.NET y SQL, así que disculpen mi ignorancia ...
Si tengo una estructura de datos en C # (por ejemplo, digamos, un vector que almacena algunas cadenas), ¿es posible almacenar el contenido del vector como está en la tabla SQL? Quiero hacer esto para que sea rápido convertir esos datos a formato vectorial lo más rápido posible sin tener que construirlo elemento por elemento. Casi como escribir datos binarios en un archivo y luego leerlo y copiarlo en una estructura asignada en C.
Creé una tabla en SQL Server 2008 para la cual un campo se define como VARBINARIO (MÁXIMO). Pensé que comenzaría con eso.
¿Podría alguien mostrarme un ejemplo de cómo me gustaría almacenar y recuperar un vector de, por ejemplo, 10 cadenas, dentro y desde ese campo? ¿Es esto posible (no puedo pensar por qué no)?
¡Gracias!
Aquí hay otro enfoque más general para las listas genéricas. Tenga en cuenta que el tipo real almacenado en la lista también debe ser serializable
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;
}
}
Luego en el código del cliente:
List<string> stringList = new List<string>() { "January", "February", "March" };
byte[] data = SerializeList<string>(stringList);
Una forma básica de almacenar / recuperar esta matriz de bytes podría ser utilizar objetos SQLClient simples:
SqlParameter param = new SqlParameter("columnName", SqlDbType.Binary, data.Length);
param.Value = data;
etc...
En primer lugar, existe la ruta obvia de simplemente crear una estructura relacional y asignar el objeto a los campos en la base de datos.
En segundo lugar, si tiene un objeto que es serializable, puede almacenarlo en el servidor SQL. Lo he hecho ocasionalmente, y he usado el tipo de datos de texto en SQL Server para almacenar el XML.
Opinión: prefiero almacenar objetos serializados como XML en lugar de datos binarios. ¿Por qué? Como puede leer realmente lo que hay allí (para la depuración), y en SQL Server, puede usar XQuery para seleccionar datos del objeto serializado. Según mi experiencia, la ganancia de rendimiento del uso de datos binarios no valdrá la pena en comparación con tener datos que es más fácil de depurar y se puede usar de una manera psicorelacional. Eche un vistazo a las capacidades XQuery de SQL Server . Incluso si no planeas usarlo de inmediato, no hay razón para ponerte en una esquina.
Puede ver algunos ejemplos usando NetDataContractSerializer .
Creo que lo que llamas un vector es una Lista <> en C #. Eche un vistazo en System.Collections.Generic. Puede usar NetDataContractSerializer para serializar una lista de 3 cadenas como:
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();
}
}
}
Este ejemplo simplemente serializa una lista, emite la serialización a la consola y luego prueba que estaba hidratada correctamente en la otra cara. Creo que puede ver que desde aquí puede volcar la secuencia de la memoria en una cadena y escribirla en la base de datos, o usar otro tipo de flujo que una secuencia de memoria para hacerlo.
Recuerde hacer referencia a System.Runtime.Serialization para obtener acceso a NetDataContractSerializer.
Si vas a hacer eso (y supongo que es técnicamente posible ), podrías usar un archivo plano: no tiene sentido usar una base de datos relacional.
Suponiendo que los objetos están marcados con [Serializable]
o implementan ISerializable
la clase BinaryFormatter
ofrece una forma sencilla de hacerlo.
Si no, estás viendo un código personalizado (no trivial).
[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
}
}
Tengo más experiencia con las bases de datos relacionales que con c #, pero la serialización binaria es un camino aceptable, ya que permite que todo el estado del objeto se guarde en la base de datos. La serialización XML es prácticamente la misma, aunque los tipos genéricos no están permitidos.
Hay razones para ser flexible. No debe permitirse que las reglas o directrices para la estructura de la base de datos impidan la creatividad. Dado el primer hilo aquí, puedo ver un enfoque híbrido para almacenar columnas seriales y restrictivas también. Muchas aplicaciones se pueden mejorar enormemente al mantener la mente abierta a las posibilidades.
De todos modos, aprecié la perspectiva de los novatos sobre el asunto. Nos mantiene a todos frescos