14

I'd like to serialize some LINQ generated objects and store them in a table as a binary field (Never you mind why). I'd like to be able to write some code that looks something like this:

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");

Currently that fails even though I've marked the generated classes as [Serializable] because one of the LINQ inherited classes is not. Is it even possible to do this?

Mykroft
  • 13,077
  • 13
  • 44
  • 72

4 Answers4

18

With linq-to-sql (from tags), then yes: you can mark the dmbl as serializable, which uses the [DataContract]/[DataMember] approach. You do this by setting the "Serialization Mode" to "Unidirectional" in the designer, or you can do it in the dbml itself:

<Database ... Serialization="Unidirectional">...

You can then use DataContractSerializer or NetDataContractSerializer to write this (as xml or binary respectively). If you need something portable (i.e. not MS/.NET specific), then protobuf-net will serialize data-contracts using the "protocol buffers" spec.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    how come when i tried to do this, and try to serialize to memcached, it's not working? :| – DucDigital Jan 23 '10 at 17:02
  • @DucDigital - does memcached support `DataContractSerializer`? Or does it just use `BinaryFormatter`? In which case you need to add `[Serializable]`. Let me know... – Marc Gravell Jan 23 '10 at 19:09
  • You have to add Serializable in to your classes, but why i mean is that, i cannot serialize the linq objects, i even i tried with several wraper to make sure if i can save to Memcached. I tried to change to Unidirectional but no helps, you can check out my examples in this opening question: http://stackoverflow.com/questions/2122081/is-there-anyway-to-serilize-linq-object-for-memcached . hope we can solve this since there really no documents about this – DucDigital Jan 24 '10 at 03:50
  • 1
    This doesn't seem to work when using an entity which has properties of type `EntitySet` when serializing by using `NetDataContractSerializer` :( – Oleks Aug 28 '12 at 15:37
  • Thanks a lot!! you are the best! – CoderKK Mar 20 '16 at 05:53
6

Following Marc Gravell's advice I wrote the following two blocks of code which worked beautifully:

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);

The Attach() call fills in the foreign key dependencies for me and associates the item with the data context.

Mykroft
  • 13,077
  • 13
  • 44
  • 72
5

MSDN: Serialization (LINQ to SQL)

Bryan Watts
  • 44,911
  • 16
  • 83
  • 88
3

Linq classes are partial classes. You can change the definition to mark the classes as implementing ISerializable and then provide the code...

public partial class User : ISerializable
{
  // implement GetObjectData here
}

There might still be issues with deserialization, however (I'm not 100% on this). An alternative is to use xml serialization and implement IXmlSerializable, which has methods for serializing and deserializing, allowing you to control the entire process...