Question

I want to add a history feature for one of my application's entities. My application is using linq to sql as O/RM. The solution I have selected for saving previous versions of entity is to serialize old version and save serialized versions somewhere.

Anyway, I was looking for the best way to serialize linq to sql entities. One of the best solutions I found was simply setting serialization mode to Unidirectional in DataContext object, and then use .net serializer. It seems that the method works well.

But, my question is, do this method have any side effect on data context or any performance hit? For example, does lazy loading of objects works intact after turning unidirectional serialization mode on?

I've searched a lot but found nothing.

And, do you think I should go another way to serialize objects? Any cheaper method?

PS 1: I don't like using DTOs, because I should maintain compatibility between DataContext object and DTOs.

PS 2: Please note, that the application I'm working on is relatively large and currently under heavy load. So I should be careful about changes in O/RM behavior or performance issues, because I could not review the entire application + online versions.

Thanks a lot :)

Was it helpful?

Solution

Re "and then use .net serializer", the intent of unidirectional mode is to support DataContractSerializer (specifically). The effect is basically just the addition of the [DataContract]/[DataMember] flags, but: based on experience, and despite your reservations, I would strongly advise you to go the DTO route:

  • ORMs, due to lazy loading of both sub-collections and properties (sometimes) makes it very hard to predict exacty what is going to happen
  • and at the same time, make it hard to monitor when data load is happening (N+1 in your serialization code can go un-noticed)
  • you have very little control over the size of the model (how many levels of descendants etc) are going to be serialized
  • and don't even get me started on parent navigation
  • the deserialized objects will not have a data-context, which means that their lazy loading won't work - this can lead to unexpected behaviours
  • you can get into all sorts of problems if you can't version your data model separately from your serialization model
  • there are some... "peculiarities" that impact LINQ-to-SQL and serialization (from memory, the most "fun" one is a difference in how the IList.Add and IList<T>.Add is implemented, meaning that one triggers data-change flags and one doesn't; nasty)
  • you are making everything dependent on your data model, which also means that you can never change your data model (at least, not easily)
  • a lot of scenarios that involve DTO are read-based, not write-based, so you might not even need the ORM overheads in the first place - for example, you might be able to replace some hot code-path pieces with lighter tools (dapper, etc) - you can't do that well if everything is tied to the data model

I strongly advocate biting the bullet and creating a DTO model that matches what you want to serialize; the DTO model would be incredibly simple, and should only take a few minutes to throw together, including the code to map to/from your data model. This will give you total control over what is serialized, while also giving you freedom to iterate without headaches, and do things like use different serializers

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top