c# - ¿Es posible serializar un objeto LINQ?
linq-to-sql serialization (4)
Me gustaría serializar algunos objetos generados por LINQ y almacenarlos en una tabla como campo binario (nunca te importa por qué). Me gustaría poder escribir un código que se parece a esto:
SerialTestDataContext db = new SerialTestDataContext();
relation_table row = db.relation_tables.First();
MemoryStream memStream = new MemoryStream();
BinaryFormatter bin = new BinaryFormatter();
bin.Serialize(memStream, row);
Console.WriteLine("Serilized successfully");
TestTable tt = new testTable();
tt.data = new System.Data.Linq.Binary(memStream.ToArray());
db.testTables.InsertOnSubmit(tt);
db.SubmitChanges();
Console.WriteLine("Inserted successfully");
Actualmente eso falla aunque he marcado las clases generadas como [Serializable] porque una de las clases heredadas de LINQ no lo está. ¿Es posible hacer esto?
Con linq-to-sql (desde etiquetas), entonces sí: puede marcar el dmbl como serializable, que usa el enfoque [DataContract] / [DataMember]. Para ello, establezca el "Modo de serialización" en "Unidireccional" en el diseñador, o puede hacerlo en el propio dbml:
<Database ... Serialization="Unidirectional">...
Luego puede usar DataContractSerializer o NetDataContractSerializer para escribir esto (como xml o binary respectivamente). Si necesita algo portátil (es decir, no específico de MS / .NET), entonces protobuf-net serializará los contratos de datos utilizando la especificación "buffer de protocolo".
Las clases de Linq son parciales. Puede cambiar la definición para marcar las clases como implementando ISerializable y luego proporcionar el código ...
public partial class User : ISerializable
{
// implement GetObjectData here
}
Sin embargo, puede haber problemas con la deserialización (no estoy 100% al respecto). Una alternativa es usar la serialización xml e implementar IXmlSerializable , que tiene métodos para serializar y deserializar, lo que le permite controlar todo el proceso ...
Siguiendo el consejo de Marc Gravell, escribí los siguientes dos bloques de código que funcionaban maravillosamente:
relation_table row = db.relation_tables.First();
MemoryStream memStream = new MemoryStream();
NetDataContractSerializer ndcs = new NetDataContractSerializer();
ndcs.Serialize(memStream, row);
byte[] stuff = memStream.toArray();
memStream = new MemoryStream(stuff);
row = ndcs.Deserialize(memStream);
db.relation_tables.Attach(row);
Console.WriteLine(row.data_table1.somedata + ": " + row.more_data);
La llamada a Attach () rellena las dependencias de clave externa para mí y asocia el elemento con el contexto de datos.