Click here to Skip to main content
15,860,972 members
Articles / Programming Languages / XML

Create Data Classes

Rate me:
Please Sign up or sign in to vote.
4.88/5 (31 votes)
4 Mar 2011CPOL10 min read 134.9K   2.5K   167   29
An application that creates a C# class to read/write data to/from an Access, SQLite, or XML database.

Screenshot of main form

Introduction

This is a C# class generator which will create a class file to enable reading/writing of a database in Access, SQLite, or XML format. It is intended to take the tedium out of creating such files which are pretty much boilerplate except for the field names and types. It can read in a schema in any of the above formats, allow you to edit the information, and then given a bit more information, create the C# class file. It also works in the reverse direction, allowing you to create a table in a new or existing Access or SQLite database, or a schema file for XML. Once the information is entered, you can save it as a project to make future changes easy. Projects can be saved in either Access or SQLite format - the Access 2007 runtime is available free from Microsoft and the SQLite .NET DLL is available from SourceForge (details are given in the included notes).

Before you start using the program

If you have only read this far and decided to try the program, please, please, read the file "BEFORE YOU START.txt" in the docs folder - the program needs to know where to find its database before it can work! There are other files in that folder as well that are worth reading.

Functions

  • You can create the C# class files to read/write classic ADO (ADODB), ADO.NET, SQLite, and XML databases.
  • You can read in a table schema from an existing Access, SQLite, or XML database.
  • You can create an Access, SQLite, or XML table and database.
  • You can save additional fields (e.g., calculated fields such as a List<T> from a CSV field stored in the database) with a project.
  • You can save additional functions (i.e., functions in addition to the basic functions needed to read/write data) with a project.
  • You can edit and save 'using directives' for each project.
  • You can produce 'standard' prototype functions like clearing a form, copying a record, deleting a record, saving a record etc. These assume some standard naming of toolstrip labels and text boxes like tslblRecordNumber, txtHomeAddress, etc.
  • It includes a 'Database Explorer' so you can examine the structure of tables in a database or XML schema.
  • You can include user defined types in your fields as long as they can be converted to/from a recognised data type.
  • You can save the data you enter as a project, so you can re-load it at a later stage to extend/change it.

How does it work?

To be able to read in data from one type of schema and write it to another needs a common data type. After trying to find something perfect, I ended up using the System.Data.DbType enumeration. There is a table included with the project which contains the enumeration member names, and each has been given a number called TypeID. As long as you can find the TypeID, you can look up the corresponding data types using that TypeID with a high level of accuracy.

Finding the correct TypeID is obviously core to the process.

The OleDbDataReader used with Access has a field called 'ProviderType' which maps to ADO constants like adSmallInt, adInteger, adSingle, and so on. This means that reading an Access table schema gives enough information to be very accurate about the type of data in a field. There is a table included with the project which maps the Access ProviderType to TypeID.

Less information is provided when reading an XML schema but XML databases only use standard system types. SQLiteDataReader provides the standard system types as well, so for both XML and SQlite, I have set up a table which maps system types to the TypeID.

If you read in an XML or SQLite schema and want to use it to create an Access table, then you will need to fine tune the data types in the Field Editor, which allows you to choose the data type by the System.Data.DbType enumeration.

Getting the fields into the program

For a program like this to be of any use, it has to be as easy as possible to get the fields into it.

If you have an existing Access, SQLite, or XML table/schema, you can read that straight into the program. If you have an existing C# class file, you can use the 'Import Fields List' form to convert a list of fields from that file. You can also import fields set out in a list consisting of the DB Type enum, then a space, then the field name, or a list with the field name first and the DB Type enum second.

Finally, you can enter the fields manually in the 'Import Fields List' form which includes a 'Quick Input' section with a combo box containing the DB Type enums and a textbox for the field name, or enter them one by one using the Field Editor.

The full details are given in a text file included with the project.

Class file produced

If we start with a class called JTestData, the program will produce a single class file called JTestData.cs containing:

  • The JTestData class - this also includes a region for additional fields, so if you keep a CSV list of data in the database as a string, you can add a function in this region to convert it to a List<T>.
  • JTestIndexData - a lightweight index class consisting, by default, the Key Field and the string override, although you can include other fields if you wish. This allows you to get a List<JTestIndexData> to use in a listview or combobox, allowing users to select records easily without having to read in the whole database.
  • JTestUpdater - a static class which reads/writes the database and has a region Additional Functions, where you can put additional functions beyond the standard functions required to read/write the database.

Additional fields and functions are saved with the project so they are not lost when you re-create the class file.

When you first open the produced C# class in Visual Studio, it won't be formatted very well. Press Ctrl+K+D (thanks to Frank D for that shortcut) and it should be formatted in the way Visual Studio normally formats your files. There will be a few "TODO" comments in the C# source. Just check these and make sure they represent what you want.

Code example

The table tblDataTypes (referred to above) also includes the following fields:

  • ADOConversionPrefix
  • ADOConversionSuffix
  • SQLiteConversionPrefix
  • SQLiteConversionSuffix
  • SQLiteUpdateSuffix

For user defined types, the prefixes/suffixes are stored with the fields rather than in tblDataTypes. When creating the class file, the program looks up these prefixes/suffixes and inserts them in the code as follows:

Reading data:

ADO.NET:
C#
testDataADONET.JDate = Convert.ToDateTime(dataRow["JDate"]);

That is quite straightforward, it converts the object it reads from the database directly into DateTime.

SQLite:
C#
testDataSQLite.JDate = DateTime.FromBinary(Convert.ToInt64(dataRow["JDate"]));
testDataSQLite.JBoolean = Convert.ToInt32(dataRow["JBoolean"]) > 0;

A little more complex, SQLite has a limited number of data types so the DateTime is stored as an INTEGER and then the program uses the .NET function DateTime.FromBinary to convert the 64 bit integer to a DateTime. Bool is also stored as an INTEGER, with false being represented by zero and true being anything else.

And a user-defined type in ADO.NET:

C#
testDataADONET.JUserDefined = 
  (JCommon.ClassDataTypes)Convert.ToInt32(dataRow["JUserDefined"]);

This user defined type is actually an enum used in the program, which is stored as an Int32 in the database and converted to the user defined type when it is read from the database.

Writing data:

ADO.NET:
C#
commandInsert.Parameters.Add(new OleDbParameter("@JDate",testDataADONET.JDate));
SQLite:
C#
commandInsert.Parameters.Add(new SQLiteParameter(
                             "@JDate",testDataSQLite.JDate.ToBinary()));
commandInsert.Parameters.Add(new SQLiteParameter("@JBoolean", 
                             testDataSQLite.JBoolean ? 1 : 0));

As you can see, we use a .NET function to convert a DateTime to INTEGER for SQLite. Since SQLite has no boolean data type, we enter 1 for true and zero for false.

And a user-defined type in ADO.NET:

C#
commandInsert.Parameters.Add(new OleDbParameter("@JUserDefined",
                            (Int32)testDataADONET.JUserDefined));

This converts the user defined type to an Int32 to store in the database.

The update commands are produced in the same way.

As you can see, the program uses the conversion prefixes/suffixes stored in tblDataTypes to create the commands. There is a function to add/edit data types in the program so additional types can be added or the prefixes/suffixes updated if needed. It is probably not a good idea to delete data types as they may be needed by your individual projects.

For user defined types, the conversion prefixes/suffixes are stored with the field data rather than in tblDataTypes.

Background

I wrote this program a couple of years ago to help me convert Access databases into XML and it has grown from there. I don't use XML for databases any more, but I do write quite a lot of programs that need to read/write databases and I wanted a quick way to create the necessary class files.

In earlier versions, I kept the TypeID for each field in the Tag of the ListViewItem but this was a bit flaky. From version 3 onwards, each field is saved as a JFieldsData in the project database, and is linked back to the saved project by the Parent Record Number. Until a project is saved, the Parent Record Number is not known so is zero. When a project is saved, this is updated to the actual Parent Record Number. If you don't save the project, those records with a Parent Record Number of zero will be deleted when you exit the program.

I have worked hard to iron out bugs from this latest version, and I have updated those sections that use hard coded fields like Record Number so they now use the Key Field. The program now properly honors the scope of the fields set for each project.

I have been using the program extensively and have tried to ensure I have fixed the problems that have come to light, but most programs only break when other people start using them so I would appreciate any feedback!

There is a test process built into the program which I have worked through (see Test Process.txt in the Tests folder) without problems.

It was suggested (by BigJim61) that I consider using CodeDOM and I have looked at that. While it would be quite useful for creating the basic class file, when it comes to the updater, I ended up just using code snippets so I didn't see much advantage of using CodeDOM over the WriteLine process I have used. I will have another look in the future, though, as it does look interesting.

I did keep the program's database in LocalUserAppDataPath in versions up to version 3 to make it Vista/Win7 friendly. However, after a near catastrophe with a hard drive, I have now put it under the project folder. I don't keep any data on my 'C:' drive and, knowing this, I don't back it up - you can probably work out the rest of the story!

History

  • 19th December, 2006 - First version.
  • 21st November, 2007 - First update.
  • 6th January, 2011 - Quite a major update to version 2.
  • 2nd February, 2011 - Again a major update to version 3.
    • It now provides full support for SQLite.
    • You can now declare a user defined field type - as long as they can be converted to one of the DB Enum types.
    • There is an option to preview the class file.
    • The data format for saved projects has changed substantially. I previously used a comma separated list for fields, but the addition of SQLite and user defined fields needed more information and something more robust. It also facilitates the addition of other databases, perhaps SQL, in the future. There is a function to convert saved projects from the old format to the new in the program.
  • 1st March, 2011 - Another major update to version 4.
    • Individual forms are used for user input rather than pages on the main form.
    • Hard coded field names weeded out.
    • Class scope properly honored.
    • Intensive bug testing.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Retired
United Kingdom United Kingdom
I have been a keen hobbyist programmer since getting my first computer - a Vic 20 (you had to be able to write programs then since few programs were available and all were expensive).
Retired and now living in Pewsey, Wiltshire, where I spend (far too much of) my time writing computer programs to keep my mind active.

Comments and Discussions

 
GeneralMy vote of 5 Pin
member6014-May-12 18:28
member6014-May-12 18:28 
QuestionHow to import sqlite database Pin
Member 155760814-Jan-11 21:02
Member 155760814-Jan-11 21:02 
AnswerRe: How to import sqlite database Pin
Jeff Gaines14-Jan-11 23:26
Jeff Gaines14-Jan-11 23:26 
AnswerRe: How to import sqlite database Pin
Jeff Gaines2-Feb-11 22:29
Jeff Gaines2-Feb-11 22:29 
GeneralMy vote of 4 Pin
BigJim618-Jan-11 14:43
BigJim618-Jan-11 14:43 
GeneralRe: My vote of 4 Pin
Jeff Gaines8-Jan-11 22:10
Jeff Gaines8-Jan-11 22:10 
GeneralFantastic Job Pin
RajeshPune2-Jul-08 3:11
RajeshPune2-Jul-08 3:11 
GeneralThis comes in handy Pin
Bert delaVega15-Apr-08 7:17
Bert delaVega15-Apr-08 7:17 
GeneralGreat Pin
Danielsue3-Nov-07 18:53
Danielsue3-Nov-07 18:53 
GeneralDatabase Pin
jarell3120-Jun-07 11:03
jarell3120-Jun-07 11:03 
AnswerRe: Database Pin
eddyep27-Nov-07 21:03
eddyep27-Nov-07 21:03 
JokeBest Pin
Recep GUVEN13-Jun-07 9:46
Recep GUVEN13-Jun-07 9:46 
Generaleasier shortcut for reformatting Pin
FrankD25-Dec-06 2:08
FrankD25-Dec-06 2:08 
GeneralRe: easier shortcut for reformatting Pin
Toli Cuturicu8-Jan-11 21:13
Toli Cuturicu8-Jan-11 21:13 
GeneralRe: easier shortcut for reformatting Pin
Jeff Gaines8-Jan-11 21:43
Jeff Gaines8-Jan-11 21:43 
GeneralRe: easier shortcut for reformatting Pin
Toli Cuturicu9-Jan-11 2:10
Toli Cuturicu9-Jan-11 2:10 
GeneralRe: easier shortcut for reformatting Pin
Jeff Gaines9-Jan-11 2:24
Jeff Gaines9-Jan-11 2:24 
GeneralRe: easier shortcut for reformatting Pin
Toli Cuturicu9-Jan-11 2:27
Toli Cuturicu9-Jan-11 2:27 
GeneralRe: easier shortcut for reformatting Pin
Jeff Gaines9-Jan-11 3:11
Jeff Gaines9-Jan-11 3:11 
GeneralRe: easier shortcut for reformatting Pin
Toli Cuturicu9-Jan-11 8:55
Toli Cuturicu9-Jan-11 8:55 
GeneralRe: easier shortcut for reformatting Pin
T_uRRiCA_N11-Jan-11 1:34
professionalT_uRRiCA_N11-Jan-11 1:34 
QuestionWhat about msde/sql server 2005 Express edition? Pin
Rob Eckert19-Dec-06 14:05
Rob Eckert19-Dec-06 14:05 
AnswerRe: What about msde/sql server 2005 Express edition? Pin
Jeff Gaines19-Dec-06 22:32
Jeff Gaines19-Dec-06 22:32 
GeneralThank YOu! Pin
asflowlaapp19-Dec-06 12:20
asflowlaapp19-Dec-06 12:20 
GeneralRe: Thank YOu! Pin
Identity.Classified18-Feb-07 20:36
Identity.Classified18-Feb-07 20:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.