PC Review


Reply
Thread Tools Rate Thread

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

 
 
Stephan Elsner
Guest
Posts: n/a
 
      8th Mar 2007
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
 
 
 
 
Neil Cowburn
Guest
Posts: n/a
 
      9th Mar 2007
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" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>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
 
Stephan Elsner
Guest
Posts: n/a
 
      9th Mar 2007
> 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
 
Ignacio Machin \( .NET/ C# MVP \)
Guest
Posts: n/a
 
      9th Mar 2007
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" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>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
 
Ginny Caughey [MVP]
Guest
Posts: n/a
 
      9th Mar 2007
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:(E-Mail Removed)...
> 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" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>>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
 
Guest
Posts: n/a
 
      9th Mar 2007
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:(E-Mail Removed)...
> 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" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>>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

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Where are Data Forms for lists (tables) in Excel 2007? =?Utf-8?B?UmVlZCBQLiBXeWF0dA==?= Microsoft Excel Misc 2 2nd Jul 2007 12:00 PM
best practise for using sql connection in c# windows application Milsnips Microsoft ADO .NET 3 16th Apr 2007 09:07 PM
Making more memory available to application?Im making a memory intense application, the application is supposed to open a prettylarge image (about 9200*10200 in 300Dpi) yosh@liquidzone.net Microsoft Dot NET Framework Forms 0 6th Dec 2004 08:16 PM
best practise for application closing on Pocket pc Rn Microsoft Dot NET Compact Framework 1 19th May 2004 09:12 PM
Best practise making a Data Access layer in .NET. Geir Holme Microsoft ADO .NET 5 17th Mar 2004 10:45 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 06:17 PM.