Saved Query Serialization issue when upgrading from 2.5 to 2.6

Posts   
 
    
mercuryred
User
Posts: 10
Joined: 31-Oct-2008
# Posted on: 31-Oct-2008 17:56:19   

Hi,

I've been working on an important medical research application which required Saved Query functionality. To implement this, we serialized the the relation predicate bucket that formed the query, and stored the serialized object in the database.

BinaryFormatter f = new BinaryFormatter();
f.AssemblyFormat = FormatterAssemblyStyle.Simple;
MemoryStream ms = new MemoryStream();
f.Serialize(ms, bucket);

string text = Convert.ToBase64String(ms.ToArray());

We can then deserialize the object at will to re-run the saved query.

BinaryFormatter f = new BinaryFormatter();
f.AssemblyFormat = FormatterAssemblyStyle.Simple;
byte[] filterBytes = Convert.FromBase64String(predicateString);
MemoryStream ms = new MemoryStream(filterBytes);

object obj = f.Deserialize(ms);
RelationPredicateBucket bucket = (RelationPredicateBucket)obj;

This was working perfectly until we had to upgrade to LLBL 2.6 (varchar(max) field was causing problems with grid paging). LLBL 2.5 objects in an LLBL 2.6 environment do not go down well. Our design flaw is starting to bite!

We are resigned to upgrading all our llbl 2.5 serialized objects to llbl 2.6. Has anyone done this before? Is this the best solution for this scenario?

I would appreciate it if someone helps us on this. Thanks.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 31-Oct-2008 20:07:41   

mercuryred wrote:

(varchar(max) field was causing problems with grid paging)

Could you elaborate more on this problems?

If I understand correctly you are serializing v2.5 objects, then deserializing on v2.6 objects. Is that correct?

David Elizondo | LLBLGen Support Team
mercuryred
User
Posts: 10
Joined: 31-Oct-2008
# Posted on: 04-Nov-2008 09:06:33   

Hi,

You are correct. We have lots of serialized version 2.5 LLBL (Relation Predicate) Buckets stored in the database. Now That we've had to upgrade to version 2.6, we need to deserialise the version 2.5 buckets, convert them to version 2.6 buckets, so we can run the query.

I am wondering if anybody has done this already.

Thanks

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 04-Nov-2008 10:08:08   

I think there are some breaking changes which prevents you from doing so.

I don't have another solution for the persisted 2.5 serialized relationPredicateBuckets.

mercuryred
User
Posts: 10
Joined: 31-Oct-2008
# Posted on: 04-Nov-2008 10:26:57   

Thanks Walaa,

I have already thought about the breaking changes. My thoughts on the way forward, is to iterate through each predicate element in the 2.5 bucket, and use this info to assemble a v2.6 predicate.

This is the only solution I see.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 04-Nov-2008 10:43:47   

Could you elaborate a bit about what _specific _problems you run into when using the v2.5 objects in v2.6?

because it might be that with some custom code which alters the predicates after deserialization (in v2.6 and then serializes them back) will work.

Frans Bouma | Lead developer LLBLGen Pro
mercuryred
User
Posts: 10
Joined: 31-Oct-2008
# Posted on: 05-Nov-2008 14:20:19   

At the moment, I am getting the following error when I attempt to deserialize my v2.5 bucket, as I have removed all references to version 2.5 from my solution.

Could not load file or assembly 'SD.LLBLGen.Pro.ORMSupportClasses.NET20, Version=2.5.0.0, Culture=neutral, PublicKeyToken=ca73b74ba4e3ff27' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference

I have not tried to find a quick fix in having v2.5 objects running in v2.6 environment because:

  • I don`t think there is one! E.g. The objects have possibly different interfaces
  • I am mindful that this will happen again when we upgrade to the next version of LLBL, and I`d like to have all my saved queries in the one version of LLBL.

My plan is to create a utility that references both v2.5 and v2.6 assemblies. I will deserialize my current saved queries into v2.5 buckets, create a corresponding bucket in v2.6, and save the v2.6 serialized version to the database.

I was just wondering if anybody has done this before.

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 05-Nov-2008 15:54:56   

Since you are migrating to 2.6 and most probably you are going to migrate to future versions.

I don't know if it's too late or not, but what about saving Linq queries (if possible) instead of the RelationPredicateBuckets.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 05-Nov-2008 16:43:24   

mercuryred wrote:

At the moment, I am getting the following error when I attempt to deserialize my v2.5 bucket, as I have removed all references to version 2.5 from my solution.

Could not load file or assembly 'SD.LLBLGen.Pro.ORMSupportClasses.NET20, Version=2.5.0.0, Culture=neutral, PublicKeyToken=ca73b74ba4e3ff27' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference

I have not tried to find a quick fix in having v2.5 objects running in v2.6 environment because:

  • I don`t think there is one! E.g. The objects have possibly different interfaces
  • I am mindful that this will happen again when we upgrade to the next version of LLBL, and I`d like to have all my saved queries in the one version of LLBL.

My plan is to create a utility that references both v2.5 and v2.6 assemblies. I will deserialize my current saved queries into v2.5 buckets, create a corresponding bucket in v2.6, and save the v2.6 serialized version to the database.

I was just wondering if anybody has done this before.

if that's the error, you can use an assembly redirect in your own application's app.config file. <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="SD.LLBLGen.Pro.ORMSupportClasses.NET20" publicKeyToken="ca73b74ba4e3ff27" culture="neutral"/> <bindingRedirect oldVersion="2.5.0.0" newVersion="2.6.0.0"/> </dependentAssembly> </runtime>

this will make the code to load the type data from v2.6. Serializing it again will refer to v2.6 types. Does that make things loadable again?

Frans Bouma | Lead developer LLBLGen Pro
mercuryred
User
Posts: 10
Joined: 31-Oct-2008
# Posted on: 05-Nov-2008 17:47:57   

Thanks for you help,

I pasted in the config setting that you sent, and I now get the following error:

Member '_typeConverterToUse' was not found.

It was worth a try though!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 06-Nov-2008 10:31:38   

In which class exactly?

You can do several things: 1) create a surrogate type to make things load. A surrogate is a way to load data into a type with deserialization which isn't serialized with that type. See the MSDN on surrogates and remoting 2) with the v2.6 sourcecode, on the class which gives the error, implement ISerializable and test if the value for the specific property is in the input (by reading it in an object variable, using a try/catch which swallows the exception. this way you can make things load.

It depends on how much data you have to deserialize of course. If it's a couple of elements which you can re-create easily, it might not be worth the effort.

Frans Bouma | Lead developer LLBLGen Pro
mercuryred
User
Posts: 10
Joined: 31-Oct-2008
# Posted on: 06-Nov-2008 12:16:11   

Otis wrote:

In which class exactly?

RelationPredicateBucket

My code for deserializing is below:

BinaryFormatter f = new BinaryFormatter();
f.AssemblyFormat = FormatterAssemblyStyle.Simple;
byte[] filterBytes = Convert.FromBase64String(predicateString);
MemoryStream ms = new MemoryStream(filterBytes);

object obj = f.Deserialize(ms);
RelationPredicateBucket bucket = (RelationPredicateBucket)obj;

The error is happening at ' f.Deserialize(ms)'

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 06-Nov-2008 15:46:54   

mercuryred wrote:

Otis wrote:

In which class exactly?

RelationPredicateBucket

Please post the stack trace as relationpredicatebucket never had that member variable.

My code for deserializing is below:

BinaryFormatter f = new BinaryFormatter();
f.AssemblyFormat = FormatterAssemblyStyle.Simple;
byte[] filterBytes = Convert.FromBase64String(predicateString);
MemoryStream ms = new MemoryStream(filterBytes);

object obj = f.Deserialize(ms);
RelationPredicateBucket bucket = (RelationPredicateBucket)obj;

The error is happening at ' f.Deserialize(ms)'

That's logical, that call starts the deserialization process wink

Have you looked into surrogates?

Frans Bouma | Lead developer LLBLGen Pro
mercuryred
User
Posts: 10
Joined: 31-Oct-2008
# Posted on: 07-Nov-2008 12:01:03   

I have not looked at Surrogates yet. It will be next week when I get around to it, and I'll keep you updated on my progress.

Thanks for your help

mercuryred
User
Posts: 10
Joined: 31-Oct-2008
# Posted on: 14-Nov-2008 17:03:33   

I wrote the code to upgrade my relational predicate buckets from version 2.5 to 2.6, and it all worked great.

Surrogates didn't really help my case as i still need to provide a mapping between my de serialised object, and my LLBL 2.6 object.

My solution involved referencing both v2.5 and v2.6 versions of LLBL (SD.LLBLGen.Pro.ORMSupportClasses.NET20). I then recursively went through each relation, and predicate in the bucket, so i could add the v2.6 equivalent to my new bucket.

I compared the results of my old and new buckets, and the same results are returned.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 14-Nov-2008 18:41:57   

Glad it worked out so well! simple_smile

Btw, you didn't get any namespace problems when referencing types with the same names twice (from different assemblies) ?

Frans Bouma | Lead developer LLBLGen Pro
mercuryred
User
Posts: 10
Joined: 31-Oct-2008
# Posted on: 18-Nov-2008 10:27:34   

I used namespace aliasing to differentiate between the 2.5 types and the 2.6 types.