PC Review
Forums
Newsgroups
Microsoft DotNet
Microsoft Dot NET Compact Framework
CF2.0 application using in memory data tables or lists - best practise
Forums
Newsgroups
Microsoft DotNet
Microsoft Dot NET Compact Framework
CF2.0 application using in memory data tables or lists - best practise
![]() |
CF2.0 application using in memory data tables or lists - best practise |
|
|
Thread Tools | Rate Thread |
|
|
#1 |
|
Guest
Posts: n/a
|
I am developing a time recording application that uses several lists
of data (customers, projects etc). There is not much data, it can be held in memory and there is no need for mobile sql server. The lists act like relational database tables and they shoul be exported as one xml document. Now my questions: 1. My first idea was to create objects like Customers etc. and store them in a BindingList<> to easily bind the list to a DataGrid for display. I found out that XmlSerializer throws an exception " ...DataList is inaccessible due to its protection level". DataList is a class derrived from BindingList with one additional method: class DataList<T> : System.ComponentModel.BindingList<T> where T : DataSet { public T getSet(int id) { foreach (DataSet ds in this) { if (ds.Id == id) { return (T) ds; } } return null; } public DataList() { } } "DataSet" in this case is my own DataSet whis is a base class for all Classes containing one Row of Data (in german "Datensatz"). Dont mix up with the ADO DataSet. No Idea why this exception occurs. 2. Is this a usable design at all? Or is it better to greate a virtual database structure in a DataSet object? Ok, it would be easyer to serialize (create xml) and deserialize later, but I need an oo wrapper then, so there is much more to code... Hou would you solve this problem? Thanks for any hints /Stephan |
|
|
|
#2 |
|
Guest
Posts: n/a
|
I think that assuming there is no need to persist the data tables is a bit
of a faulty premise. How do you plan to recover should the battery run flat or if the user soft resets the device? Both these scenario will result in the loss of your in-memory tables unless you persist them in some way. The reason that the XmlSerializer is failing on the your DataList class is because its scope is marked as internal. By default, all classes without an access modifier are internal. Set the access modifier to public. Also, the signature for the class is overly complicated. Change this: class DataList<T> : System.ComponentModel.BindingList<T> where T : DataSet to this: public class DataList : System.ComponentModel.BindingList<DataSet> Make sure that DataList list has a public, parameterless constructor and it should work with the XmlSerializer. -- Neil Cowburn Principal Partner OpenNETCF Consulting, LLC. Managed Code in the Embedded World http://www.opennetcf.com/ http://www.smartdeviceframework.com/ "Stephan Elsner" <elsni@web.de> wrote in message news:1173392182.962994.135270@c51g2000cwc.googlegroups.com... >I am developing a time recording application that uses several lists > of data (customers, projects etc). There is not much data, it can be > held in memory and there is no need for mobile sql server. The lists > act like relational database tables and they shoul be exported as one > xml document. Now my questions: > > 1. My first idea was to create objects like Customers etc. and store > them in a BindingList<> to easily bind the list to a DataGrid for > display. I found out that XmlSerializer throws an exception > " ...DataList is inaccessible due to its protection level". DataList > is a class derrived from BindingList with one additional method: > > class DataList<T> : System.ComponentModel.BindingList<T> where > T : DataSet > { > public T getSet(int id) > { > foreach (DataSet ds in this) > { > if (ds.Id == id) > { > return (T) ds; > } > } > return null; > } > > public DataList() { } > } > > "DataSet" in this case is my own DataSet whis is a base class for all > Classes containing one Row of Data (in german "Datensatz"). Dont mix > up with the ADO DataSet. No Idea why this exception occurs. > > 2. Is this a usable design at all? Or is it better to greate a virtual > database structure in a DataSet object? Ok, it would be easyer to > serialize (create xml) and deserialize later, but I need an oo > wrapper then, so there is much more to code... > > Hou would you solve this problem? > > Thanks for any hints > > /Stephan > |
|
|
|
#3 |
|
Guest
Posts: n/a
|
> I think that assuming there is no need to persist the data tables is a bit
> of a faulty premise. How do you plan to recover should the battery run flat > or if the user soft resets the device? Both these scenario will result in > the loss of your in-memory tables unless you persist them in some way. No, there should be persistance, I need the xl serializer for this (and for data export) > The reason that the XmlSerializer is failing on the your DataList class is > because its scope is marked as internal. By default, all classes without an > access modifier are internal. Set the access modifier to public. Also, the > signature for the class is overly complicated. Change this: Thank you! I forgot 'public' in some class definitions > class DataList<T> : System.ComponentModel.BindingList<T> where T : DataSet > to this: > public class DataList : System.ComponentModel.BindingList<DataSet> I dont need to change that, it now works like a charm (after adding a parameterless constructor in DataList) Thank you! |
|
|
|
#4 |
|
Guest
Posts: n/a
|
Hi,
I have a similar escenario than you , an amount of data that can be handled in memory so no need of ceSql. Not only that but the app has been aroudn for a couple of years and it has had a couple or refiniments to load faster the data. At least in the first installment of the framework using XML was extremely costly. What I do is create classes to represent my business ( Customers, Products, etc ) , then I keep the lists as static property of the same class This is an example of the Client class, as you see I have a Find method just as you proposed. public class Client { public int ClientID; public string ClientName; public static Client[] Clients= new Client[0]; public static Client Find( int clientID) { for(int i=0; i< Clients.Length; i++) if( Clients[i].ClientID == clientID ) return Clients[i]; return null; } public static void Clear( int count) { Clients = new Client[count]; } } Now the tricky part is how to load the lists in the most efficient and fast manner. There are several ways of doing it, after trying several ways I found that the fastest way was using a text file, instead of delimiting the fields with a comma you use a non-printable char that you know for sure will not appear inside a field, this avoid having to check if the field separator char appear inside a field. Another improvement was using an array for store the lists (as you can see above), this improve the performanace over using an ArrayList for example and makes the code cleaner avoiding the need for casting. Loading the file is easy now, the file has this struct: TableName #OfItems row1 row2 .... This is the code to load the data public static void LoadClients(string targetfile) { StreamReader reader = new StreamReader( targetfile); string currentline; int currenttable=-1; int index=-1; while( (currentline = reader.ReadLine())!=null) { switch ( currentline) { case "Client" : currenttable=0; index = 0; Client.Clear( Convert.ToInt32( reader.ReadLine() )); continue; } string[] currentrow = currentline.Split( new char[] {(char)20}); switch ( currenttable) { case 0 : try { Client cli = new Client(); cli.ClientID= Convert.ToInt32(currentrow[0]); cli.ClientName = currentrow[1]; cli.ClientAddr= currentrow[2]; Client.Clients[ index++] = cli; continue; } } //switch } //while reader.Close(); How to generate the file in the other side is your homework ![]() "Stephan Elsner" <elsni@web.de> wrote in message news:1173392182.962994.135270@c51g2000cwc.googlegroups.com... >I am developing a time recording application that uses several lists > of data (customers, projects etc). There is not much data, it can be > held in memory and there is no need for mobile sql server. The lists > act like relational database tables and they shoul be exported as one > xml document. Now my questions: > > 1. My first idea was to create objects like Customers etc. and store > them in a BindingList<> to easily bind the list to a DataGrid for > display. I found out that XmlSerializer throws an exception > " ...DataList is inaccessible due to its protection level". DataList > is a class derrived from BindingList with one additional method: > > class DataList<T> : System.ComponentModel.BindingList<T> where > T : DataSet > { > public T getSet(int id) > { > foreach (DataSet ds in this) > { > if (ds.Id == id) > { > return (T) ds; > } > } > return null; > } > > public DataList() { } > } > > "DataSet" in this case is my own DataSet whis is a base class for all > Classes containing one Row of Data (in german "Datensatz"). Dont mix > up with the ADO DataSet. No Idea why this exception occurs. > > 2. Is this a usable design at all? Or is it better to greate a virtual > database structure in a DataSet object? Ok, it would be easyer to > serialize (create xml) and deserialize later, but I need an oo > wrapper then, so there is much more to code... > > Hou would you solve this problem? > > Thanks for any hints > > /Stephan > |
|
|
|
#5 |
|
Guest
Posts: n/a
|
Ignacio,
This is a great approach and I've used it myself. Best of all, with a business class like this, if the requirements suddenly change later as they did for me, it's not a lot of work to just change the load, store and search logic to use SqlCE instead. -- Ginny "Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions.com> wrote in message news:uj0nZNlYHHA.3628@TK2MSFTNGP02.phx.gbl... > Hi, > > I have a similar escenario than you , an amount of data that can be > handled in memory so no need of ceSql. Not only that but the app has been > aroudn for a couple of years and it has had a couple or refiniments to > load faster the data. At least in the first installment of the framework > using XML was extremely costly. > > What I do is create classes to represent my business ( Customers, > Products, etc ) , then I keep the lists as static property of the same > class > > This is an example of the Client class, as you see I have a Find method > just as you proposed. > > public class Client > { > public int ClientID; > public string ClientName; > > public static Client[] Clients= new Client[0]; > > public static Client Find( int clientID) > { > for(int i=0; i< Clients.Length; i++) > if( Clients[i].ClientID == clientID ) > return Clients[i]; > return null; > } > > public static void Clear( int count) > { > Clients = new Client[count]; > } > } > > > Now the tricky part is how to load the lists in the most efficient and > fast manner. > > There are several ways of doing it, after trying several ways I found that > the fastest way was using a text file, instead of delimiting the fields > with a comma you use a non-printable char that you know for sure will not > appear inside a field, this avoid having to check if the field separator > char appear inside a field. > > Another improvement was using an array for store the lists (as you can see > above), this improve the performanace over using an ArrayList for example > and makes the code cleaner avoiding the need for casting. > > Loading the file is easy now, the file has this struct: > TableName > #OfItems > row1 > row2 > ... > > This is the code to load the data > public static void LoadClients(string targetfile) > { > StreamReader reader = new StreamReader( targetfile); > string currentline; > int currenttable=-1; > int index=-1; > while( (currentline = reader.ReadLine())!=null) > { > switch ( currentline) > { > case "Client" : > currenttable=0; > index = 0; > Client.Clear( Convert.ToInt32( reader.ReadLine() )); > continue; > > } > string[] currentrow = currentline.Split( new char[] {(char)20}); > switch ( currenttable) > { > case 0 : > try > { > > Client cli = new Client(); > > cli.ClientID= Convert.ToInt32(currentrow[0]); > cli.ClientName = currentrow[1]; > cli.ClientAddr= currentrow[2]; > > Client.Clients[ index++] = cli; > continue; > > } > } //switch > } //while > > reader.Close(); > > > How to generate the file in the other side is your homework ![]() > > "Stephan Elsner" <elsni@web.de> wrote in message > news:1173392182.962994.135270@c51g2000cwc.googlegroups.com... >>I am developing a time recording application that uses several lists >> of data (customers, projects etc). There is not much data, it can be >> held in memory and there is no need for mobile sql server. The lists >> act like relational database tables and they shoul be exported as one >> xml document. Now my questions: >> >> 1. My first idea was to create objects like Customers etc. and store >> them in a BindingList<> to easily bind the list to a DataGrid for >> display. I found out that XmlSerializer throws an exception >> " ...DataList is inaccessible due to its protection level". DataList >> is a class derrived from BindingList with one additional method: >> >> class DataList<T> : System.ComponentModel.BindingList<T> where >> T : DataSet >> { >> public T getSet(int id) >> { >> foreach (DataSet ds in this) >> { >> if (ds.Id == id) >> { >> return (T) ds; >> } >> } >> return null; >> } >> >> public DataList() { } >> } >> >> "DataSet" in this case is my own DataSet whis is a base class for all >> Classes containing one Row of Data (in german "Datensatz"). Dont mix >> up with the ADO DataSet. No Idea why this exception occurs. >> >> 2. Is this a usable design at all? Or is it better to greate a virtual >> database structure in a DataSet object? Ok, it would be easyer to >> serialize (create xml) and deserialize later, but I need an oo >> wrapper then, so there is much more to code... >> >> Hou would you solve this problem? >> >> Thanks for any hints >> >> /Stephan >> > > |
|
|
|
#6 |
|
Guest
Posts: n/a
|
And using a Hashtable instead of an array would improve the speed even more,
especially if you have a fair number of items. -- Chris Tacke - Embedded MVP OpenNETCF Consulting Managed Code in the Embedded World www.opennetcf.com -- "Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions.com> wrote in message news:uj0nZNlYHHA.3628@TK2MSFTNGP02.phx.gbl... > Hi, > > I have a similar escenario than you , an amount of data that can be > handled in memory so no need of ceSql. Not only that but the app has been > aroudn for a couple of years and it has had a couple or refiniments to > load faster the data. At least in the first installment of the framework > using XML was extremely costly. > > What I do is create classes to represent my business ( Customers, > Products, etc ) , then I keep the lists as static property of the same > class > > This is an example of the Client class, as you see I have a Find method > just as you proposed. > > public class Client > { > public int ClientID; > public string ClientName; > > public static Client[] Clients= new Client[0]; > > public static Client Find( int clientID) > { > for(int i=0; i< Clients.Length; i++) > if( Clients[i].ClientID == clientID ) > return Clients[i]; > return null; > } > > public static void Clear( int count) > { > Clients = new Client[count]; > } > } > > > Now the tricky part is how to load the lists in the most efficient and > fast manner. > > There are several ways of doing it, after trying several ways I found that > the fastest way was using a text file, instead of delimiting the fields > with a comma you use a non-printable char that you know for sure will not > appear inside a field, this avoid having to check if the field separator > char appear inside a field. > > Another improvement was using an array for store the lists (as you can see > above), this improve the performanace over using an ArrayList for example > and makes the code cleaner avoiding the need for casting. > > Loading the file is easy now, the file has this struct: > TableName > #OfItems > row1 > row2 > ... > > This is the code to load the data > public static void LoadClients(string targetfile) > { > StreamReader reader = new StreamReader( targetfile); > string currentline; > int currenttable=-1; > int index=-1; > while( (currentline = reader.ReadLine())!=null) > { > switch ( currentline) > { > case "Client" : > currenttable=0; > index = 0; > Client.Clear( Convert.ToInt32( reader.ReadLine() )); > continue; > > } > string[] currentrow = currentline.Split( new char[] {(char)20}); > switch ( currenttable) > { > case 0 : > try > { > > Client cli = new Client(); > > cli.ClientID= Convert.ToInt32(currentrow[0]); > cli.ClientName = currentrow[1]; > cli.ClientAddr= currentrow[2]; > > Client.Clients[ index++] = cli; > continue; > > } > } //switch > } //while > > reader.Close(); > > > How to generate the file in the other side is your homework ![]() > > "Stephan Elsner" <elsni@web.de> wrote in message > news:1173392182.962994.135270@c51g2000cwc.googlegroups.com... >>I am developing a time recording application that uses several lists >> of data (customers, projects etc). There is not much data, it can be >> held in memory and there is no need for mobile sql server. The lists >> act like relational database tables and they shoul be exported as one >> xml document. Now my questions: >> >> 1. My first idea was to create objects like Customers etc. and store >> them in a BindingList<> to easily bind the list to a DataGrid for >> display. I found out that XmlSerializer throws an exception >> " ...DataList is inaccessible due to its protection level". DataList >> is a class derrived from BindingList with one additional method: >> >> class DataList<T> : System.ComponentModel.BindingList<T> where >> T : DataSet >> { >> public T getSet(int id) >> { >> foreach (DataSet ds in this) >> { >> if (ds.Id == id) >> { >> return (T) ds; >> } >> } >> return null; >> } >> >> public DataList() { } >> } >> >> "DataSet" in this case is my own DataSet whis is a base class for all >> Classes containing one Row of Data (in german "Datensatz"). Dont mix >> up with the ADO DataSet. No Idea why this exception occurs. >> >> 2. Is this a usable design at all? Or is it better to greate a virtual >> database structure in a DataSet object? Ok, it would be easyer to >> serialize (create xml) and deserialize later, but I need an oo >> wrapper then, so there is much more to code... >> >> Hou would you solve this problem? >> >> Thanks for any hints >> >> /Stephan >> > > |
|
![]() |
|
| Thread Tools | |
| Rate This Thread | |
|
|

Main Page 


