?
Solved

Loss of object Info during serialization into sql server database in C# csharp .net

Posted on 2009-04-22
8
Medium Priority
?
506 Views
Last Modified: 2013-12-17
I think I am experiencing loss of information while serializing an object.
There is an object of type cMasterTest (parent), from which object of type cHP3245A_testParam (child) is derived. In other words, cHP3245A_testParam inherits cMasterTest.

I have been successful in storing nested serialized objects in an sql server database by inserting them into a memory stream, converting to an array of bytes, and storing them in a VARBINARY(MAX) field, and retrieving everything back.

This I would think would be simpler, but it doesn't seem to work: (Step 1) I take my object, explicitly cast it to its parent, then serializing that and storing it in a db. Then I (Step 2) retrieve the serialized object from the db, de-serialize it into the parent object, explicity cast it back to the child object.

Basically, once casting and inheritance is involved, I seem to have loss of information.

Please, if someone knows what is going on, please help me.
//*** (1) GET DATA ***\\
 
iHandleTests interfaceToUserControl =
                TDuc as iHandleTests;
 
// Here we are getting cHp3245A casted into cMasterTest and returned via
// the getTestParameters() method.
cMasterTest testParameters = interfaceToUserControl.getTestParameters();
 
/* The retrieval has been successfull because If I explicitly convert testParameters 
to cHP3245A_testParam object at this point there would be no loss of information, 
so I know I received the right data */
 
 
//*** (2) STORE DATA IN DATABASE ***\\
 
ms = new MemoryStream();
bf = new BinaryFormatter();
bf.Serialize(ms, testParameters);
sqlParam_data = new SqlParameter("@data", SqlDbType.VarBinary);
sqlParam_data.Value = ms.ToArray();
// sqlParam is then inserted to database
 
 
//*** (3) RETRIEVE DATA FROM DATABASE ***\\
 
sqlDataReader.Read();
bf = new BinaryFormatter();
ms = new MemoryStream((byte[])sqlDataReader["test_object"]);
cMasterTest cmt = (cMasterTest)bf.Deserialize(ms);
 
// PROBLEM HERE Conversion NOT successful -- Loss of information
cHP3245A_testParam tp = (cHP3245A_testParam)cmt;

Open in new window

0
Comment
Question by:yaronusa
  • 4
  • 4
8 Comments
 
LVL 15

Expert Comment

by:oobayly
ID: 24206261
I assume the the loss of information are the properties in unique to cHP3245A_testParam, and the information succesfuly serialised is that which is defined in cMasterTest?

As you're casting the cHP3245A_testParam to cMasterTest, the serializer is only serialising the properties in cMasterTest (It doesn't know about the properties in cHP3245A_testParam).
0
 

Author Comment

by:yaronusa
ID: 24211207
Is there a way to make the parent object know about the child's info? If not, then I guess I will return a serialized version of the data, as opposed to a parent object which is then serialized.

So is there a way for the parent object to know about the child's info, to make it persistant so that when serialization takes place it knows? I'm guessing not....


0
 
LVL 15

Expert Comment

by:oobayly
ID: 24213300
Actually, just test a basic set of inherited classes, and if you serialize an object which has been casted to its parent class, there shouldn't be an issue. Apologies for that, I was thinking about the XmlSerializer's behaviour. I've also realised it Serializes private members too.

Have you tried serializing & deserializing without the rounds trip to the database, and verifying that that works. That way you can confirm the database storage isn't the issue.

Also, are you implementing your own serialization in this class?
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      BinaryFormatter sz = new BinaryFormatter();
 
      cMasterTest testParameters = interfaceToUserControl.getTestParameters();
      sz.Serialize(ms, testParameters);
 
      ms.Position = 0;
      cMasterTest cmt = (cMasterTest)bf.Deserialize(ms);

Open in new window

0
 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

 

Author Comment

by:yaronusa
ID: 24213809
I have successfully serialized to memory and de-serialized from memory without round trip to the database, so that works. In the code below you can see the test I ran.

Does this mean it is a database issue? I am using SQL Server 2005 Express. The name of the table is tblSerializedTests. The script that creates the table is in the code snippet.

The way I enter and retrieve the serialized info from the database, you can see that in my original posting above.

What other info can I give you or what's something else I can try?

One interesting note: When I serialize to the memory stream, it is of 724 length and 1024 capacity. But when I de-serialize, it is of length 725 and also 725 capacity. Not sure if that means anything, but I would expect the memory streams to be equal in length.



//*** SUGGESTED TEST (THIS WORKS) ***\\
MemoryStream ms2 = new MemoryStream();
BinaryFormatter bf2 = new BinaryFormatter();
bf2.Serialize(ms2, testParameters);
ms2.Position = 0;          
 
// Deserialize to parent
cMasterTest cmt = (cMasterTest)bf2.Deserialize(ms2);
 
 // Deserialize to child
 cHP3245A_testParam param = (cHP3245A_testParam)cmt; // Success!
// *** END OF SUGGESTED TEST ***\\
 
//*** DATABASE RELATED ***\\
-- Create test object table
CREATE TABLE tblSerializedTests
 (unique_id integer not null,
  test_name VARCHAR(25) not null,
  test_object VARBINARY(MAX) not null);
//*** END DATABASE RELATED ***\\

Open in new window

0
 
LVL 15

Accepted Solution

by:
oobayly earned 2000 total points
ID: 24213981
Very strange that the data being returned from the database is longer that the data inserted.
I've just tried serialising an object into a VARBINARY(MAX) field and the array returned is identical to that inserted.

Have you compared the byte array being inserted to the byte array being returned. Are they identical except the additional byte being returned?

I'd suggest running some tests on the table, ie inserting random lengths of data, and comparing the data returned.
0
 

Author Comment

by:yaronusa
ID: 24255677
The solution, it turns out, was quite simple. My SQL statement was not pulling the object I thought it was pulling from the database. The CLUE to this should have been the different in number of bytes going into the database then going out.

In any case, I resolved the SQL statement and it now works!!!

Thank you for leading me on the right path, I could not have done it without people like you.
0
 

Author Closing Comment

by:yaronusa
ID: 31573321
The solution, it turns out, was quite simple. My SQL statement was not pulling the object I thought it was pulling from the database. The CLUE to this should have been the different in number of bytes going into the database then going out.

In any case, I resolved the SQL statement and it now works!!!

Thank you for leading me on the right path, I could not have done it without people like you.
0
 
LVL 15

Expert Comment

by:oobayly
ID: 24258485
No worries, glad to be of assistance.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question