Daniel Essin
|
|
Group: Forum Members
Posts: 235,
Visits: 309
|
I have built a bo library that corresponds to 3 tables in my database. The one I am working with is a table of users. It is my intention to test the new serialize to stream function.
There are 3 issues here
The table schema looks like this:
new DataColumn("ID", typeof(System.String)),
new DataColumn("LAST_NAME", typeof(System.String)),
new DataColumn("FIRST_NAME", typeof(System.String)),
new DataColumn("MI", typeof(System.String)),
new DataColumn("TITLE", typeof(System.String)),
new DataColumn("LIC_NO", typeof(System.String)),
new DataColumn("DEA", typeof(System.String)),
new DataColumn("EMP_NO", typeof(System.String)),
new DataColumn("INSVC_DATE", typeof(System.DateTime)),
new DataColumn("OSVC_DATE", typeof(System.DateTime))
etc...
I created a Strataframe windows app and added boAllUsers1 instance to the form and added a button with the follwoing handler:
private void button1_Click(object sender, EventArgs e)
{
Stream myStream;
boAllUsers1.NewRow();
boAllUsers1.ID = "FRED";
boAllUsers1.SerializeToStream(myStream);
BOLibrary.boAllUsers allUsers = (BOLibrary.boAllUsers)BusinessLayer.DeserializeBusinessObject(myStream);
MessageBox.Show(allUsers.ID);
}
1)---------------------------------------------------------------
The first error I get is in the attached jpeg and I don't understand it.
2)---------------------------------------------------------------
The second error is when I try to execute:
boAllUsers1.ID = "FRED";
The error is:
{"Input string was not in a correct format.Couldn't store in ID Column. Expected type is Int32."}
Since this is a string field in the DB and the BO was built knowing that it is a string field, why is it complaining that I cannot put a string in an integer field?
3)---------------------------------------------------------------
Since .NET does not provide a constructor that will create a new empty stream, perhaps it would be better if SerializeToStream returned a Stream and SerializeToByteArray returned a ByteArray rather than taking them as input parameters?
Thank you
|
|
|
Daniel Essin
|
|
Group: Forum Members
Posts: 235,
Visits: 309
|
Addendum...
You didn't by any chance make the assumption that all PK's would be numeric?
When I look at the datatable inside boAllusers1, I see that after executing the NewRow() function, the ID (pk) field is populated with a -1.
This is the behavior that I normally associate with providing autonumbering of an integer field. In my shcema the ID (pk) is a string field that receives the user's login username.
|
|
|
Trent Taylor
|
|
Group: StrataFrame Developers
Posts: 6.6K,
Visits: 6.9K
|
I will look further into the the behavior you are referring to tomorrow, but the message you were unfamiliar with is a standard .NET message that is presented to the developer when a reference to a DLL or other assembly can be seen by the solution from more than a single location and with different versions. For example, you may have one version of an assembly in the GAC and another in the folder your solution is attempting to run on. When this occurs, .NET presents the developer with a message to add a direct reference to the app.config file. This is .NETs way of resolving a version conflict at compile time.
As for the other, I will look into it more tomorrow. As of right now I have not been able to reproduce the behavior you mentioned. But it is getting late and I am sleep deprived, so I will give it a fresh look tomorrow.
|
|
|
Daniel Essin
|
|
Group: Forum Members
Posts: 235,
Visits: 309
|
The more I think about it, the more sure I am that bo.SeializeToStream should return Stream and bo.SerializeToByteArray should return ByteArray[].
In addition to the issue of not being able to create an empty stream for this function to fill, is that the way they are currently written without the parameter being a ref parameter, you could pass in a stream or a byteArray but you would never get it back out at all.
|
|
|
StrataFrame Team
|
|
Group: StrataFrame Developers
Posts: 3K,
Visits: 2.5K
|
The bo.SerializeToStream() method cannot return a stream because the framework has no idea what type of stream you are expecting (System.IO.MemoryStream, System.Net.NetworkStream, System.IO.FileStream), and the method certainly cannot return a System.IO.Stream because the class is abstract and it cannot create an instance of it. The SerializeToStream(System.IO.Stream) method accepts the stream TO WHICH you want the data to be written. And there is no need to accept the stream, write to it, and then return the same stream you just passed.
The System.IO.Stream does not need to be passed because ByRef because classes are reference objects, so passing a class by reference is only necessary if the actual reference is going to change (i.e., after the method call, the parameter you pass will be replaced by a different object).
If you need to create a new empty stream, you can use System.IO.MemoryStream st = new System.IO.MemoryStream(); and that will create a new empty stream. You can also create a new System.IO.FileStream by specifying the filename in the constructor.
The SerializeToByte() method already returns a System.Byte[], so it's works in the same manner as you would expect.
|
|
|
Daniel Essin
|
|
Group: Forum Members
Posts: 235,
Visits: 309
|
In order to separate operational issues from philosophical discussion, I have posted the errors that occurred when trying to use this function in a separate message.
As far as the philosophical issues is concerned, I have a preference for functions like this returning an object as a result for the following reasons:
1) It makes it possible to nest the function that creates the new stream within a function call that consumes the stream.
2) If I read the .NET framework correctly (please correct me if necessary as I am kind of new to this area of .NET), there are only 4 basic types of streams: MemoryStream, FileStream, BufferedStream and .Net.NetworkStream. Any other type of stream that one chose to create would be done by subclassing one of these. This would admit several solutions to introducing a function that returned a new stream:
a) Create 4 functions. SerializeToMemoryStream, SerializeToFileStream, SerializeToBufferedStream and SerializeToNetworkStream.
b) Create the SerializeToStream function to take an enum as the input parameter. The Enum would be something like:
enum SerializeToStreamType{
MemoryStream,
FileStream,
BufferedStream
NetworkStream }
In either case if the user was working with a custom class that was subclassed from one of these, they could cast the return value to the type of their custom class.
3) It would create a syntactic unity between SerializeToStream and SerializeToByteArray which would soothe by obsessive, compulsive soul.
Clearly what you have created so far is workable (with the exception of the issues raised in the other post). If what I have suggested is really not possible because of other technical factors that you understand better than I, I can certainly live with it the way it is. I hope I have at least done an adequate job of explaining my preference and why I raised the issue.
Thank you.
|
|
|
StrataFrame Team
|
|
Group: StrataFrame Developers
Posts: 3K,
Visits: 2.5K
|
Aye, Daniel, I agree with you on the semantics, the operational restrictions are unfortunately rather different...
1) You cannot just "create" many of these types of streams without access to certain other objects (i.e. you can generally only aquire a NetworkStream from its connected socket) and we would end up with Lord knows how many overloads for each SerializeToStreamType method (SerializeToFileStream would itself have 15 different overloads, one for each constructor overload on the FileStream class, allowing you to specify how you would want us to create the FileStream).
2) I don't know of many .NET methods that return a stream (other than, of course, GetStream() which gets a reference to the current stream used by the object on which it was called).
3) Most methods require that you pass them the stream on which you want them to write rather than returning a new stream of a given type. For instance: the System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize() method accepts a stream and an object. The stream you pass is the stream on which you want the serialized object to be written, and the object is the object you want serialized. So, our methods as the currently stand match the current methodology used by .NET with concern for streams.
|
|
|
Daniel Essin
|
|
Group: Forum Members
Posts: 235,
Visits: 309
|
Your "tutorial" has brought me up to speed on this very rapidly and, again, your logic is inescapable.
Thank you
|
|
|
Trent Taylor
|
|
Group: StrataFrame Developers
Posts: 6.6K,
Visits: 6.9K
|
Good, I am glad we could help.
|
|
|
StrataFrame Team
|
|
Group: StrataFrame Developers
Posts: 3K,
Visits: 2.5K
|
I don't now about inescapable, I've been known to be wrong just as much as the next guy And, oh yeah, we're looking into where we have the primary key cast as an integer...
|
|
|