PC Review Forums Newsgroups Microsoft DotNet Microsoft Dot NET Compact Framework CF2.0 application using in memory data tables or lists - best practise

Reply

CF2.0 application using in memory data tables or lists - best practise

 
Thread Tools Rate Thread
Old 08-03-2007, 10:16 PM   #1
Stephan Elsner
Guest
 
Posts: n/a
Default CF2.0 application using in memory data tables or lists - best practise


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

  Reply With Quote
Old 09-03-2007, 11:07 AM   #2
Neil Cowburn
Guest
 
Posts: n/a
Default Re: CF2.0 application using in memory data tables or lists - best practise

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
>


  Reply With Quote
Old 09-03-2007, 01:09 PM   #3
Stephan Elsner
Guest
 
Posts: n/a
Default Re: CF2.0 application using in memory data tables or lists - best practise

> 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!

  Reply With Quote
Old 09-03-2007, 02:00 PM   #4
Ignacio Machin \( .NET/ C# MVP \)
Guest
 
Posts: n/a
Default Re: CF2.0 application using in memory data tables or lists - best practise

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
>



  Reply With Quote
Old 09-03-2007, 02:11 PM   #5
Ginny Caughey [MVP]
Guest
 
Posts: n/a
Default Re: CF2.0 application using in memory data tables or lists - best practise

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
>>

>
>


  Reply With Quote
Old 09-03-2007, 02:39 PM   #6
Guest
 
Posts: n/a
Default Re: CF2.0 application using in memory data tables or lists - best practise

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
>>

>
>



  Reply With Quote
Reply



Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off