What is the best way to store instances of a class to file/database?
We have a base class called Command and loads of derived classes.
Users create instances of these classes by adding commands to a graphical designer
where they can configure them. (Set the properties).
We then need a way to store these "commands" to a file without losing
any information.
One idea was to use db4o, but the GPL license is not acceptable for this project.
Any suggestions or code samples?
Update:
(In order to "de-blurryfie" my question :p)
The generated code might look something like:
command[i++] = new DelayInSecondsCommand(2);
command[i++] = new DaliRequestCommand(1, false, 254);
command[i++] = new DaliRequestCommand(2, false, 254);
command[i++] = new DaliRequestCommand(3, false, 254);
command[i++] = new WaitInSecondsCommand(2);
command[i++] = new DaliRequestCommand(1, false, 0);
command[i++] = new DaliRequestCommand(2, false, 0);
command[i++] = new DaliRequestCommand(3, false, 0);
command[i++] = new JumpCommand(0);
But then with loads of different commands.
I know it's possible with .NET serialization, altough I've never used it before,
but I was wondering if there are better alternatives, like I said db4o seems nice but the license doesn't fit the project.
Update 2:
Thank you for the replies. I'll probably go with the serialization solution now,
but I'll look into the other options as well. F.Y.I. data is stored in a SQL Compact database.
Are you trying to save the data in tables? or as blob/clob data? Since you mention files, I assume the latter: any of the standard .NET serializers should be fine - they all support inheritance etc. I'd consider for DataContractSerializer, as this combines the field-level support (like BinaryFormatter), and the assembly-independence of XmlSerializer.
You could also consider more esoteric things like protobuf-net.
So: what is it you need to do that won't work under the standard serializers?
serialization does the trick! Serialization is nothing more than converting an object or a connected graph of objects into a stream of bytes (in order to persist the current state of the object). This can be a binary stream, XML or whatever. You don't have to do this conversion by your own since .Net has great support for serialization. Once you serialized an object, you are free to store this data to a file or database. Likewise, a stream of bytes representing a serialized object can be deserialized into an object which will have the same state as the original one.
Btw: Once you have a serialized stream of bytes, you can apply some more functions on it, e.g. compression or encryption.
Pretty blurry question, why don't you just use .NET's built-in serialization possibilities (e.g. XmlSerializer).
db40 also provides a commerical license but it has been recently bought by versant so maybe you may want to look at that. This sort of database is known as object orientated database and is a way of creating persistant instances of classes which is very different to relational databases that work using tables.
This (wikpedia.org) is a good read on object orienated databases and this (also wikipedia) is a list of some of the available options.
In my opinion object databases are much better & more powerfull than relational and I will only use relational databases like mysql if I really have to (not very often).
I would recommomend you watch these videos and download the trial.
Serialization is a great way to store this type of data. See http://blog.paranoidferret.com/index.php/2008/06/20/csharp-tutorial-xml-serialization/
There is http://www.neodatis.org. Its LGPL, but the time I used there was only a implementation for Java. Now, there's a "beta" release for C#, but I didn't tested.
Related
I have an object which
does not have the Serializable attribute set
Has properties, who's type, does not have the Serializable attribute set
I do not have control over (meaning i cannot edit the class)
I tried reading THIS, it talks about substitution classes to fix this when using Sharpserializer but frankly, I don't understand how to do this when I don't know the properties of my object.
are there some of serialization frameworks that can do this?
Edit: I'm looking into protobuf.net
I cannot figure out how to get it to work in my scenario though - Im hoping Marc will swing by to save the day? :) -
I read this which is the exact same problem as mine, but I'm still getting
"Type is not expected and no contract can be inferred"
when using
private static byte[] ClienToBytes(IScsClient client)
{
using (var memoryStream = new MemoryStream())
{
RuntimeTypeModel.Default.Add(typeof(IScsClient), true).SetSurrogate(typeof(BinaryFormatterSurrogate<IScsClient>));
Serializer.Serialize(memoryStream, client);
return memoryStream.ToArray();
}
}
am I using the RunTimeTypeModel wrong?
I would try protobuf-net. Take a look here:
http://code.google.com/p/protobuf-net/
Quote from Website:
protocol buffers is the name of the binary serialization format used by Google for much of their data communications. It is designed to be:
small in size - efficient data storage (far smaller than xml)
cheap to process - both at the client and server
platform independent - portable between different programming architectures
extensible - to add new data to old messages
I have a regular C# class called "vehicle" with properties like Name, NumberPlate, MaxSpeed, etc.
All the data for the class is stored in a SQLite Database where I have a Table "Car" and "Boat". The tables colums have the same names as the class properties (however, there are more columns than class properties - vehicle is a more generic abstraction). At the moment, I have to assign the result of the query individually one by one like this:
while (await statement.StepAsync())
{
myVehicle.Name = statement.Columns["Name"];
//[...]
myVehicle.MaxSpeed = decimal.TryParse(statement.Columns["MaxSpeed"]);
}
Additionally, I have to check if some columns exist ("Car" and "Boat" have a different set of columns) which is more code than I'd like it to be.
I read about EntityFramework to map my db table to my class - but that seems overkill. My requirement is to map properties and columns that have the same name and ignore everything else.
Is there a "easy" (dev time, lines of code) way to map my table columns to my class?
Thanks for reading!
The restrictions in phone 8 mean that a lot of the standard answers to this ("just use {some ORM / micro-ORM}") won't apply, since they don't work on phone 8. You can probably use reflection for a lot of this, but: reflection can be (relatively) slow, so it depends on how much data you will be processing. If it is occasional and light: fine, reflect away.
Runtime meta-programming (the tricks used by libraries like "dapper" in full .NET to make these things really fast) is not available on restricted runtimes, so if you want to avoid lots of boiler-plate that leaves build-time meta-programming. At the simplest, I wonder if you could use something like T4 to automate creating these methods for you as C#. There are also ways to use the reflection-emit API to construct assemblies (at build-time) for phone 8, but that is a pretty hard-core route.
My thoughts:
if the amount of types here isn't huge, just write the code
if you have a lot of types, or you just feel like it, consider a build-time code-generation meta-programming step; you might even think "hmm, is this something I could make available to the community?"
of course, the first thing to do is to check that such a thing doesn't already exist
There is a little helper which might fit your case. Basically, it will take a dictionary and try it's best to populate a objects properties using reflection. I didn't try it by myself though.
You'd simply do something like:
while (await statement.StepAsync())
{
myVehicle = DictionaryToObject<Car>(statement.Columns);
}
It might need some further work to get it running but maybe a good start.
I saw this Q&A MongoDB Norm query nested objects, but it seems to apply to strongly-typed objects only.
Is there a way to do a find or update a nested field on an Expando object (https://github.com/atheken/NoRM/wiki/expando)? Basically, I have a simple JSON CMS tool that lets developers store document objects on the server, which would then be serviced to Flash clients. I would need provide a simple service where a developer can create a JSON object, save it, make nested queries and also update these objects.
Since, the data structure is not known, I thought this would be a perfect place to use MongoDB. Unfortunately, .Net seems better suited for strongly-typed data structures.
Any ideas? Thank you!
As Andrew said you dont get intelligence support for expando objects since the document type is unknown at compile time. Instead you can query it like this
var query = new Expando();
query["comments.Author"] = Q.Equals("R");
Mongo mongo = new Mongo(connection);
var reer = mongo.GetCollection<Expando>("Blog").Find(query).ToList();
Explanation:
This retrieves the all the Blog documents by querying the embedded document comments (comments.Author="R").
You can certainly do this, just GetCollection("collectionName") or GetCollection("collectionName") and you can do all the standard operations. The downside of using Expando is that you don't get intellisense or LINQ, but in your case, that is ok.
I have to send information too a third party in an XML format they have specified, a very common task I'm sure.
I have set of XSD files and, using XSD.exe, I have created a set of types. To generate the XML I map the values from the types within my domain to the 3rd party types:
public ExternalBar Map(InternalFoo foo) {
var bar = new ExternalBar;
bar.GivenName = foo.FirstName;
bar.FamilyName = foo.LastName;
return bar;
}
I will then use the XMLSerializer to generate the files, probably checking them against the XSD before releasing them.
This method is very manual though and I wonder if there is a better way using the Framework or external tools to map the data and create the files.
LINQ to XML works quite well for this... e.g.
XElement results = new XElement("ExternalFoos",
from f in internalFoos
select new XElement("ExternalFoo", new XAttribute[] {
new XAttribute("GivenName", f.FirstName),
new XAttribute("FamilyName", f.LastName) } ));
Firstly, I'm assuming that the object properties in your existing domain map to the 3rd party types without much manipulation, except for the repetitive property assignments.
So I'd recommend just using standard XML serialization of your domain tree (generate an outbound schema for your classes using XSD), then post-processing the result via a set of XSLT stylesheets. Then after post-processing, validate the resulting XML documents against the 3rd party schemas.
It'll probably be more complicated than that, because it really depends on the complexity of the mapping between the object domains, but this is a method that I've used successfully in the past.
As far as GUI tools are concerned I've heard (but not used myself) that Stylus Studio is pretty good for schema-to-schema mappings (screenshot here).
In my web application I include all of my JavaScripts as js files that are embedded resources in the assembly, and add them to the page using ClientScriptManager.GetWebResourceUrl(). However, in some of my js files, I have references to other static assets like image urls. I would like to make those assembly resources as well. Is there a way to tokenize the reference to the resource? e.g.
this.drophint = document.createElement('img');
this.drophint.src = '/_layouts/images/dragdrophint.gif';
Could become something like:
this.drophint = document.createElement('img');
this.drophint.src = '{resource:assembly.location.dragdrophint.gif}';
I'd suggest that you emit the web resources as a dynamic javascript associative array.
Server side code:
StringBuilder script = new StringBuilder();
script.Append("var imgResources = {};");
script.AppendFormat("imgResources['{0}'] = '{1}';",
"drophint",
Page.ClientScript.GetWebResourceUrl(Page.GetType(), "assembly.location.dragdrophint.gif"));
script.AppendFormat("imgResources['{0}'] = '{1}';",
"anotherimg",
Page.ClientScript.GetWebResourceUrl(Page.GetType(), "assembly.location.anotherimg.gif"));
Page.ClientScript.RegisterClientScriptBlock(
Page.GetType(),
"imgResources",
script.ToString(),
true);
Then your client side code looks like this:
this.drophint = document.createElement('img');
this.drophint.src = imgResources['drophint'];
this.anotherimg = document.createElement('img');
this.anotherimg.src = imgResources['anotherimg'];
Hope this helps.
I don't particularly care for the exact implementation #Jon suggests, but the idea behind it is sound and I would concur that emitting these would be a good thing to do.
A slightly better implementation, though this is all subjective to some degree, would be to create a server-side model (read: C# class(es)) that represents this dictionary (or simply use an instance of Dictionary<string, string>) and serialize that to JavaScript literal object notation. That way you are not dealing with the string hacking you see in Jon's example (if that bothers you).
I concur with Jason's assessment of the initial solution I proposed, it can definitely be improved. My solution represents an older school javascript mentality (read, pre the emergence of ajax and JSON). There are always better ways to solve a problem, which one of the reasons why StackOverflow is so cool. Collectively we are better at the craft of programming than anyone of us on our own.
Based on Jason's ideas I'd revise my initial code, and revise some of what Jason suggested. Implement a C# class with two properties, the img resource id and a property that contains the WebResourceUrl. Then, where I differ some from Jason is that rather than using a Dictionary<string, string> I'd propose using a List<MyImageResourceClass>, which you can then in turn serialize to JSON (using DataContractJsonSerializer), and emit the JSON as the dynamic script, rather than manually generating the javascript using a string builder.
Why a List? I think you may find that dictionaries when serialized to JSON, at least using the DataContractJsonSerializer (fyi available with the 3.5 framework only, with the 2.0 or 3.0 framework you'd need to bolt on aspnet ajax and use is JSON serializer), are a little more cumbersome to work with than how a list would serialize. Although that is subjective.
There are implications too with your client side code. Now on the client side you'll have an array of the JSON serialized MyImageResourceClass instances. You'd need to iterate through this array creating your img tags as you go.
Hopefully, these ideas and suggestions can help get you going! And no doubt there are other solutions. I'm interested to see what comes of this.