Click here to Skip to main content
Email Password   helpLost your password?

Sample Image - CSharp_Wrapper.jpg

Introduction

Today, application development paradigm has expanded into many areas. Developers/ architects use many different approaches to keep their phase with the fast moving industry by developing applications rapidly. In all cases, the bottom lines are speed, accuracy, scalability and performance of the system they develop. When considering this, writing of database manipulation (model) class for a fairly big database can be both tedious and potentially error prone with many developers using a cut and paste solution each time. This kind of repetition leads one to consider alternative approaches based on code generation techniques, code that automatically generates the wrappers for your database. This article is written to respond to the need to deliver database driven systems very fast, preferable if the development team is small.

In this article, I don�t force developers to adapt any particular development methodology or process, as well as do not force to use any specific architecture in order to develop the system. As far as the comments I gathered so far, this type of code generation tool is most suitable for applications that have separated-class-set to manipulate the database operations.

The application generates two types of classes, one is a set of C# (referred as CS here in after) files which map into the database tables. They will have the same class name as the table name, and they will have the properties that are same as the table attributes. The other is another set of CS files which covers the basic/ standard database operations such as add, delete, update (one whole row or separately each column) and select (one whole row or separately each column). As the above figure illustrates, the developers can directly plug the auto generated code into their application's architecture. The code generation tool will only generate a set of predictable methods as described, and right now, the tool does not respond to relations that you have in the database schema as well as for complex data mining options.

Background

In practice, changing the database schema after fully or partially developing the application is a fairly common experience for many developers today. Many times, the system specification changes at the development stages of the system, or else the development methodologies we adapt require that type of restructuring/ flexibility. Then, once you change the database, as a parallel process, you got to change the model classes (if you are following the MVC � Model View Controller; architecture), in other words, the class sets that handle the database manipulation and operations. This is time consuming as well as this reduces the developer�s enthusiasm. This article presents an automated approach to solve the problem completely. There, the application will develop a set of classes that are responsible for doing most of the database manipulations, such as add, delete, update, and select field and records.

Using the Application

Application Overview

The figure illustrates a sample output of the application. Here in this example, we have used the "Sale" table as the source database table for this application. Once you provide all required details as it was described in the �Using the Application� section above, it creates two CS classes named "Sale" and "HandlerSale". Sale class is the one which maps with the column name of the table. Since the table containes two columns named �saleid� and �description�, the Sale class has two properties named saleid and description. The HandlerSale is the class that has code to do all basic database manipulations. The Handler class uses �Sale� type object as parameter and/or return type as is needed by its methods. The application generates all the T-SQL needed along with parameters as well. These things also will reside with the �Handler� class. In simple terms, once the application generates the classes, you have nothing to do other than straightaway add them to your project.

Requirements

The users who read/ test this article need to have some understanding of C# Windows Forms applications, MS SQL Server and T-SQL. Additionally, you are expected to have the Visual Studio .NET IDE and MS SQL Server 7 or higher installed in your machine (need the super user credentials to login to the DB server). After all, if you are familiar with popular application development architectures such as MVC, it would be an added advantage.

Note: If you are planning to use a SQL Server that resides in a network machine, you need to have the "SQL Server Enterprise Manager" installed in your machine to create a test database, or you need to talk to your friendly network admin to create a test database for you.

Important: To use the code, you have to add reference to the "Microsoft.ApplicationBlocks.Data.dll", which resides in the DLL folder of the "CSharp_Wrapper_src" directory.

Using the code

The application consists of four classes named:

Application Flow

The application starts as the user clicks on the "Connect and Get Data" button. The Click event fires the method named GetAllTheDetials, after initializing the connection string and getting the DataReader to read the table data of the given database.

private void lbtnConnect_Click(object sender, System.EventArgs e)
{
    if (CreateConnectionString())
    {
        GetAllTheDetials(tcGetDataReader());
        this.lbtnCreate.Enabled = true;
    }
}

Then, application creates object of type "Table" for each table and stores them in memory using a System.Collection.ArrayList named �lobjTables�. Once this is finished, user can click on the second button named "Creates Model Classes", which will fire the method below. This method is responsible for generating the code using the �lobjTablesArrayList.

private void lbtnCreate_Click(object sender, System.EventArgs e)
{
    StringBuilder sbMapClass, sbHandlerClass;
    StreamWriter swMapClass = null;
    StreamWriter swHandlerClass = null;
    foreach(Table tb in lobjTables)
    {
        try
        {
            //Get the class name for the Database Map class

            //Example Asset.cs

            sbMapClass = new System.Text.StringBuilder(tb.Name);
            sbMapClass.Append(".cs");
            //Get the Class name for the DB handler class

            //Example HandlerAsset.cs

            sbHandlerClass = new StringBuilder("Handler");
            sbHandlerClass.Append(tb.Name);
            sbHandlerClass.Append(".cs");
            
            FileInfo lobjFileInfoMapClass = new FileInfo(
                sbMapClass.ToString());
            FileInfo lobjFileInfoHandlerClass = new FileInfo(
                sbHandlerClass.ToString());
            
            swMapClass = lobjFileInfoMapClass.CreateText();
            swHandlerClass = lobjFileInfoHandlerClass.CreateText();

            swMapClass.Write(tb.MapClassTopPartCode.ToString());
            swMapClass.Write(tb.MapClassMidPartCode.ToString());
            swMapClass.Write(tb.MapClassBottomPart.ToString());

            swHandlerClass.Write(tb.HandlerClassCode.ToString());
        }
            //The file name is a directory.

        catch (System.UnauthorizedAccessException ev)
        {
            MessageBox.Show(ev.Message);
        }
            //The disk is read-only.

        catch (System.IO.IOException ev)
        {
            MessageBox.Show(ev.Message);
        }
            //The caller does not have the required permission.

        catch (System.Security.SecurityException ev)
        {
            MessageBox.Show(ev.Message);
        }
        finally 
        {
            swMapClass.Flush();
            swHandlerClass.Flush();
            swMapClass.Close();
            swHandlerClass.Close();
        }
    }
    MessageBox.Show("Done !!");
    this.lbtnCreate.Enabled = false;
}

Get Table's Name, Attributes and Types from the Database

In the above code, one of the most interesting and important section is the T-SQL command that is used to get the table name list of the database along with other additional data.

private const string SQL_GET_TABLES = "SELECT 
        table_name, 
        column_name, 
        data_type FROM information_schema.columns 
            WHERE table_name in (select table_name    
                FROM Information_Schema.Tables 
                    WHERE Table_Type='Base Table') 
        ORDER BY table_name";

Please note that you can use "*" to see all the selections other than the table_name, column_name, and data_type.

Get the Primary Key of the Table

Another important T-SQL command is the one which is used to select the primary key of a given table.

private const string SQL_SELECT_PRIMARYKEY = "SELECT 
        column_name 
        FROM information_schema.key_column_usage 
            WHERE constraint_name like 'pk%' 
                and table_name=@tablename";

Once every thing finishes, you should get a set of commented and formatted CS classes, having two classes for each table in the database. Below you see the classes generated for the table named Sale.

Sale Class Generated for the Sale Table

using System;

public class Sale
{
    /// <SUMMARY>

    /// Default Contructor

    /// <SUMMARY>

    public Sale()
    {}


    public string saleid
    { 
        get { return _saleid; }
        set { _saleid = value; }
    }
    private string _saleid;

    public string description
    { 
        get { return _description; }
        set { _description = value; }
    }
    private string _description;

    public Sale(

        string saleid, 
        string description)
    {
        this._saleid = saleid; 
        this._description = description; 
    }
}

HandlerSale Class Generated for the Sale Table

using System;
using System.Data.SqlClient;
using System.Data;
using System.IO;
using System.Text;
using Microsoft.ApplicationBlocks.Data;
/// <summary>

/// Summary description for HandlerTBN.

/// </summary>

public class HandlerSale
{
    private const string SQL_CONN_STRING 
        = "data source=PRD-01;initial catalog=ManGoDB;"
          + "integrated security=false;persist" + 
          " security info=True;User ID=sa;Password=d7972";
    private const string SQL_DELETE_Sale 
        = "DELETE FROM Sale WHERE saleid = @saleid";
    private const string SQL_SELECT_Sale 
        = "SELECT * FROM Sale WHERE saleid = @saleid";
    private const string SQL_INSERT_Sale 
        = "INSERT INTO Sale VALUES(@saleid, @description)";
    private const string SQL_UPDATE_Sale 
        = "UPDATE Sale SET saleid = @saleid," + 
          " description = @description WHERE saleid = @saleid";
    private const string SQL_UPDATE_description 
        = "UPDATE Sale SET description = @description WHERE saleid = @saleid";
    private const string SQL_SELECT_description
        = "SELECT description FROM Sale WHERE saleid = @saleid";
    private const string PARAM_saleid 
        = "@saleid";
    private const string PARAM_description 
        = "@description";
    public HandlerSale()
    {
        //

        // TODO: Add constructor logic here

        //

    }
    /// <summary>

    /// Insert a New TBN record to the table

    /// </summary>

    /// <param name="tobjTBN">Object to be inserted to the table</param>

    /// <returns>Status of the data insertion</returns>

    public bool InsertSale(Sale tobjSale)
    {
        if(tobjSale != null)
        {
            //Get the parameter list needed by the given object

            SqlParameter[] lParamArray =  GetParameters(tobjSale);
            SetParameters(lParamArray, tobjSale);
            //Get the connection

            SqlConnection con = GetConnection(SQL_CONN_STRING);
            if (con == null)
                //Connection is not created 

                return false;
            //Execute the insertion

            int i = SqlHelper.ExecuteNonQuery(
                con, 
                CommandType.Text, 
                SQL_INSERT_Sale, 
                lParamArray);
            //Dispose the Sql connection 

            con.Dispose();
            if (i ==1)
                //Done and insert the object to the table

                return true;
            else 
                //Fail to execute teh insertion

                return false;
        }
        else
            //No object found to insert

            return false;
    }
    /// <summary>

    /// Get a Object given the Object ID

    /// </summary>

    /// <param name="tstrObjectId"></param>

    /// <returns></returns>

    public Sale tcSelectSale(string tstrsaleid)
    {
        // SqlConnection that will be used to execute the sql commands

        SqlConnection connection = null;
        SqlParameter[] aParms = 
            new SqlParameter[]{
                     new SqlParameter(PARAM_saleid
                    , tstrsaleid)};
        try
        {
            try
            {
                connection = GetConnection(SQL_CONN_STRING);
            }
            catch (System.Exception e)
            {
                //lobjError = ManGoErrors.ERROR_CONNECT_TO_DB;

                //log.Error(lobjError, e);

                return null;
            }
            // Call ExecuteDataReader static method of 

            // SqlHelper class that returns an DataReader

            // We pass in an open database connection object

            // , command type, and command text

            SqlDataReader reader = SqlHelper.ExecuteReader(
                connection
                , CommandType.Text
                , SQL_SELECT_Sale
                , aParms);
            // read the contents of data reader and return the results:

            while (reader.Read())
            {
                return new Sale(
                    reader.GetString(0),
                    reader.GetString(1));
            }
            // close Reader

            reader.Close();
            return null;
        }
        catch(Exception ex)
        {
            //lobjError = ManGoErrors.ERROR_UNKNOWN;

            System.Diagnostics.Trace.WriteLine(ex.Message);
            return null;
        }
        finally
        {
            if(connection != null)
                connection.Dispose();
        }
    }
    /// <summary>

    /// Get a Column given the Object ID

    /// </summary>

    /// <param name="tstrObjectId"></param>

    /// <returns></returns>

    public string tcSelectdescription(string tstrsaleid)
    {
        // SqlConnection that will be used to execute the sql commands

        SqlConnection connection = null;
        SqlParameter[] aParms = new SqlParameter[]{
                             new SqlParameter(
                                PARAM_saleid
                                , tstrsaleid)};
        try
        {
            try
            {
                connection = GetConnection(SQL_CONN_STRING);
            }
            catch (System.Exception e)
            {
                //lobjError = ManGoErrors.ERROR_CONNECT_TO_DB;

                //log.Error(lobjError, e);

                return string.Empty;
            }
            // Call ExecuteReader static method of

            // SqlHelper class that returns an DataReader

            // We pass in an open database connection object

            // , command type, and command text

            SqlDataReader reader = SqlHelper.ExecuteReader(
                connection
                , CommandType.Text
                , SQL_SELECT_description
                , aParms);
            // read the contents of Data reader and return the result:

            while (reader.Read())
            {
                return reader.GetString(0);
            }
            // close Reader

            reader.Close();
            return string.Empty;
        }
        catch(Exception ex)
        {
            //lobjError = ManGoErrors.ERROR_UNKNOWN;

            System.Diagnostics.Trace.WriteLine(ex.Message);
            return string.Empty;
        }
        finally
        {
            if(connection != null)
                connection.Dispose();
        }
    }
    /// <summary>

    /// Delete the Profile from the Profile table

    /// </summary>

    /// <param name="tstrObjectId"></param>

    /// <returns></returns>

    public bool tcDeleteSale(string tstrsaleid)
    {
        SqlConnection connection = null;
        SqlParameter[] aParms = new SqlParameter[]{
                             new SqlParameter(
                            PARAM_saleid
                            , tstrsaleid)};
        try
        {
            connection = GetConnection(SQL_CONN_STRING);
            if (connection == null)
                return false;
            // Call ExecuteNoneQuery static method 

            // of SqlHelper class that returns an Int

            // We pass in an open database connection object

            // , command type, and command text

            int i = SqlHelper.ExecuteNonQuery(
                connection
                , CommandType.Text
                , SQL_DELETE_Sale
                , aParms);
            return true;
        }
        catch(Exception ex)
        {
            //lobjError = ManGoErrors.ERROR_UNKNOWN;

            System.Diagnostics.Trace.WriteLine(ex.Message);
            return false;
        }
        finally
        {
            if(connection != null)
                connection.Dispose();
        }
    }
    /// <summary>

    /// Update a object given the object primary key

    /// </summary>

    /// <param name="tstrobjectId"></param>

    /// <returns></returns>

    public void tcUpdateSale(Sale tobjSale)
    {
        SqlParameter[] aParms = GetParameters(tobjSale);
        SetParameters(aParms, tobjSale);
        using (SqlConnection conn = GetConnection(SQL_CONN_STRING))
        {
            // conn.Open();

            using (SqlTransaction trans = conn.BeginTransaction())
            {
                try
                {
                    SqlHelper.ExecuteNonQuery(
                        trans
                        , CommandType.Text
                        , SQL_UPDATE_Sale, aParms);
                    trans.Commit();
                }
                catch(System.Exception e)
                {
                    trans.Rollback();
                    //log.Error(lobjError, e);

                    throw;
                }
            }
        }
    }
    /// <summary>

    /// Update an Item given the object primary key

    /// </summary>

    /// <param name="tstrobjectId"></param>

    /// <returns></returns>

    public void tcUpdatedescription(
        string tstrItemId
        , string tobjData)
    {
        SqlParameter[] aParms = new SqlParameter[]{
         new SqlParameter(
         PARAM_saleid
         , tstrItemId)
        , new SqlParameter(PARAM_description, tobjData)};
        using (SqlConnection conn = GetConnection(SQL_CONN_STRING))
        {
            // conn.Open();

            using (SqlTransaction trans = conn.BeginTransaction())
            {
                try
                {
                    SqlHelper.ExecuteNonQuery(
                        trans
                        , CommandType.Text
                        , SQL_UPDATE_description
                        , aParms);
                    trans.Commit();
                }
                catch(System.Exception e)
                {
                    trans.Rollback();
                    System.Diagnostics.Trace.WriteLine(e.Message);
                    throw;
                }
            }
        }
    }
    /// <summary>

    /// Get the Parameter List for this object

    /// </summary>

    /// <param name="tobjTBN">TBN object</param>

    /// <returns>Sql Parameter List</returns>

    private SqlParameter[] GetParameters(Sale tobjSale)
    {
        SqlParameter[] objParamArray = SqlHelperParameterCache.GetCachedParameterSet(
            SQL_CONN_STRING
            , SQL_INSERT_Sale);
        if (objParamArray == null)
        {
            //Represents a parameter to a System.Data.SqlClient.SqlCommand, 

            //and optionally, its mapping to System.Data.DataSet columns. 

            objParamArray = new SqlParameter[]
            {
                new SqlParameter(PARAM_saleid, tobjSale.saleid),
                new SqlParameter(PARAM_description, tobjSale.description),
            };
            SqlHelperParameterCache.CacheParameterSet(
                SQL_CONN_STRING
                , SQL_INSERT_Sale
                , objParamArray);
        }
        return objParamArray;
    }
    /// <summary>

    /// Fill database parameters for a perticular profile

    /// </summary>

    private void SetParameters(SqlParameter[] SaleParms,Sale tobjSale)
    {
        SaleParms[0].Value = tobjSale.saleid;
        SaleParms[0].Value = tobjSale.description;
    }
    /// <summary>

    /// Create data base conection

    /// </summary>

    /// <param name="connectionString"></param>

    /// <returns></returns>

    private SqlConnection GetConnection(string tstrConnectionString)
    {
        //Represents an open connection to a SQL Server database.

        //This class cannot be inherited.

        SqlConnection dbconnection = new SqlConnection(tstrConnectionString);
        try
        {
            //Opens a database connection with the property settings

            //specified by the ConnectionString.

            dbconnection.Open();
            return dbconnection;
        }
            //Cannot open a connection without specifying a data source.

            //or The connection is already open.

        catch (System.InvalidOperationException e)
        {
            return null;
        }
            //A connection-level error occurred while opening.

        catch (System.Data.SqlClient.SqlException e)
        {
            return null;
        }
    }
}

Points of Interest

Some parts of the code still needs some improvement. At the same time, it seems to me that this application can be greatly improved to be served for multiple databases as well.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
General5 For You
Bilal Haider
5:31 4 Feb '09  
Great Job..!

although a lot of tools are available, but i appreciate ur effort and idea.

Keep it up!

A smile is a curve that sets everything straight....!

Visit my Home Page.

Generala Bug
dong zhiyong
14:54 27 Jul '07  
When the Database owns only one table,the program cannot generate the file correctly.Big Grin
GeneralVBscript version of database Wrapper?
zaz12
2:40 4 Oct '05  
Hi.
The CSharp_Wrapper is very good.
But where can I find a VBscript version of CSharp database Wrapper?

My problem is that
I need to you use ASP and not ASP.net.

I wait for any solution you will suggest me

Thanks a lot!
RobertoSmile

GeneralRe: VBscript version of database Wrapper?
Nirosh
9:45 6 Oct '05  
Time is a blocker.. for me .. I think there are couple of others people who has developed some thin similar may be you should try to use one one them..



L.W.C. Nirosh,
Technical Lead,
TextCENTRIC Technology,
Colombo,
Sri Lanka.
GeneralAbout reader.GetBytes()
solusoft
1:14 4 Aug '05  
Hi, mister, it's great article and code source has high quality, like caviar.

I see litle something in code generated by SQL Wrapper - Model Creator.

By example, I have in my DB, a table INT_VALOR_CARAC, and the table has a field name VAL_CAR, varbinary(1) type.

The ModelCreator generate this:

return new INT_VALOR_CARAC(
reader.GetInt32(0),
reader.GetInt32(1),
reader.GetBytes(2));

But reader.GetBytes(2)); not compiles !!! The method needs more arguments.

Any solution about this bug ?

Thansk everybody (needs somebody to love)
GeneralRe: About reader.GetBytes()
Nirosh
7:39 4 Aug '05  
mmm it seems to me that I have to say that this tool does not support data types such as XML, (n)varchar(max), varbinary(max) introduced in SQL Server 2005...

OK! I will address them with my next update.. I am extreamely sorry for the inconvienient..

L.W.C. Nirosh,
Colombo,
Sri Lanka.
GeneralAn Idea for Code Generator
zhengdong jin
23:03 18 May '05  
hi,Smile
I'd try to write a Code Generator for MS SQL Server, but almost all procs need to modify, so if we can write an another generator like C# Call Functions for these modified SQL Server procs, it will be ...

Steps:
1 Create Tables for a Application
2 Generate the Data Manipulate Script
3 Modify and add some SQL Server procs & functions
4 Generate call functions for Visual .Net... like C# function & VB.Net function

eReach Code Generator
GeneralGive MyGeneration a try ...
MyGeneration Software
4:08 17 Dec '04  
MyGeneration is 100% Free
MyGeneration is an extremely flexible development tool written in Microsoft .NET. MyGeneration generates code from templates that can be written in C#, VB.NET, JScript,
and VBScript. MyGeneration is great at generating ORM architectures or O/R Mapping files for architectures such as Gentle.NET, NHibernate, and others. The meta-data from your database is made available to your templates through the MyMeta API. MyGeneration supports Microsoft SQL, Oracle, IBM DB2, MySQL, PostgreSQL, Microsoft Access, FireBird, Interbase, SQLite and VistaDB.

MyGeneration also ships with a very popular .NET architecture available in C# and VB.NET known as dOOdads
See http://www.mygenerationsoftware.com dOOdads example usage (all generated for you)
C# Link VB.NET Link
GeneralRe: Give MyGeneration a try ...
Nirosh
21:49 2 Jan '05  
Thanks for the info..


L.W.C. Nirosh,
Software Engineer,
TextCENTRIC Technology,
Colombo,
Sri Lanka.
GeneralRe: Give MyGeneration a try ...
fmonroy
7:27 30 Mar '06  
MyGeneration Software: Reading on your site (on dOOdads C# usage) I didnt find any way to create a query that returns data from 2 or more joined tables, even in the "TheDeluxeQuery".

Is there a way to do it?

FM
GeneralRe: Give MyGeneration a try ...
Mike Griffin
8:44 31 Mar '06  
We use views typically. and then we generate the dOOdads off of the view. After all, were after strongly typed business entities and how do you get properties off an object that's building joins dynamically. Check out our new architecture too at http://www.entityspaces.net

GeneralRe: Give MyGeneration a try ...
fmonroy
7:16 1 Apr '06  
We are looking for a way to simplify the construction of queries and provide an "sql syntax" error free way in .net (something like sql embedded in pb) for the developers at our company.

Using views sounds a good alternative to get these strongly typed objects but it's not exactly what we are looking for because using this way developers need to manually create all the sql syntax.

I was wondering if MyGeneration could have a way of use FKs to automatically create joins between tables; but you're right, I can't figure out (yet) of an easy way to access the results of a solution like this.

EntitySpaces looks great, but we first need to migrate to the framework's v2.

Smile Thank you very much.

FM
QuestionRe: Give MyGeneration a try ...
stixoffire
13:27 30 May '08  
For a guy who is really just starting and has one project .. is there a Free Architecture that allows for eay manipulation , i.e. updating and selects of multiple tables ?

For example I have a Product but it comes in different "flavors" not as in tasting but varieties.
I have a master and then the details table. To update one table is straight forward with doodads, but two tables is not easy. I would need to get a View of the Query but how then can that be used to update.. Doodads has no easy answer.

I know I can do it by selecting the view I want for one table object and get the associated from another table object and then update each individually .. lot of extra code in there. Any Ideas or Sugestions ? I do like the Doodads b/c it is simple..

Also on another note My Generation does not support Visual FoxPro FreeTables.. I have been messing some with the source and using the MySQL provider to adapt some things b/c param key ? is the same at least in 4.0 / VFP 9.0
GeneralChecked OlyMars?
CreProDes
18:24 15 Dec '04  
Dear Nirosh,
I hope you have checked OlyMars http://www.microsoft.com/france/msdn/technologies/outils/olymars/default.asp . It provides the same solution but with support for SP's and relationships, apart from which there are plugins for creating further improvements. Though my intention was not to discourage you, what you do is a good learning task, but I would rather improve on something that already exists and provides a complete solution rather than to start from scratch again.

Hope my post is of some help to you. Have a nice day.

Regards

CC
GeneralRe: Checked OlyMars?
Nirosh
20:57 15 Dec '04  
Hi,

I am not the best DB programmer.. I started this application without knowing any of these existing tool.. full thanks to you for showing this.. but later only I realize that how corwed this market is.. yes olymars is also a good tool ... it may help me if it gives me the code as well.. but it doesn't, so I don't like to improve on that tool..

but the help is appreciated.. thanks.. and your idea is good.. yes I should start from an already existing tool than creating a one from the scratch.. there are some paths lies will see how/ where I should go..

Many thanks for the interest..
Nirosh.



L.W.C. Nirosh,
Software Engineer,
TextCENTRIC Technology,
Colombo,
Sri Lanka.
GeneralWhy not just use typed DataSets, CommandBuilders, and the SqlCommand wizard included with VS.NET
Anonymous
19:27 14 Dec '04  
I see projects like this regularly, and though I think they are good as learning tasks, I have yet to find one that does a better job than the tools MS provides for this purpose.

Typically, I use command builders unless speed is paramount, in which case I use the sproc wizard in Query Analyzer and the SqlCommand wizard...

Why write your own which takes time to build and support when there is something complete, supported, and free to VS.NET users?

GeneralRe: Why not just use typed DataSets, CommandBuilders, and the SqlCommand wizard included with VS.NET
Nirosh
20:44 14 Dec '04  
Well, First thanks for the interest shown,

Selecttion is upto you.. and if you think that command builder better suite you .. yes that is your choice.. but command builder is not a complete solution. Other thing is wizard.. if you think it is enough yes good and it is again your choice, but still it is not a complete solution.. I think if data base get change you have to use the wizard again and again to generate the SQL commands, if you have time to do that then you are lucky.. but I am not so lucky time is critical at my end, so let join together.. my attempt is not to provide a partial solution.. again this is not the final solution ... I need ideas.. while saying this, let me show you some part that you have here where you don't have in any of the tool you use. Right now this application only supports T-SQL, the SP solution is coming soon. but when you create SP yes you can use wizard. but does it generate the SP wrapper classes as well for you.. so here in this solution you get the wrapper class set as well. plus did you see the options you have when you use the select methods.. not only just selecting the whole row but this supports selecting each item (attribute) of the row as well so I am not going to repeat what I have written above in here again.. I, while respecting your views, invite you to read the article with care.. if you still see that it is useless.. then I probably have to think the way I present ideas twise..Smile



L.W.C. Nirosh,
Software Engineer,
TextCENTRIC Technology,
Colombo,
Sri Lanka.
GeneralRe: Why not just use typed DataSets, CommandBuilders, and the SqlCommand wizard included with VS.NET
DiBrun
0:15 15 Dec '04  
Dont be frustrated with the anonymous guy. When someone has made complex enterprise solutions I'm sure one gets the point.
All the hazzle with the wizards in VS is terrible, especially with regards to changes, and for queries spanning more than a single table, as well as support for various key methodologies (ID, Guid, multiple keys ...) and no serious support for handling concurrency (eg. Timestamp), and no Bulk update etc. etc.
For any advanced solution you basically still have to do all the (very time consuming) plumbing yourself.
I've been thinking about starting work on a similar project my self, but just never seem to be able to find the time.
Great work so far. Keep up the good work. I hope you will expand further on your work.

GeneralRe: Why not just use typed DataSets, CommandBuilders, and the SqlCommand wizard included with VS.NET
Nirosh
0:19 15 Dec '04  
Thanks DiBurn.. indeed I will..


L.W.C. Nirosh,
Software Engineer,
TextCENTRIC Technology,
Colombo,
Sri Lanka.
GeneralRe: Why not just use typed DataSets, CommandBuilders, and the SqlCommand wizard included with VS.NET
MyGeneration Software
5:56 17 Dec '04  
MyGeneration builds a much better wrapper (than strongly typed datasets), see above post
GeneralGreat Article...
Wallace.TL
14:55 9 Dec '04  
Keep up the good work.

TL Wallace
GeneralRe: Great Article...
Nirosh
20:40 9 Dec '04  
Thanks Wallace... same time do you have any additional feature that you need to add to this tool, if 'yes' pls let me know.. I really need ideas.. I like this to improve further..


L.W.C. Nirosh,
Software Engineer,
TextCENTRIC Technology,
Colombo,
Sri Lanka.
GeneralRe: Great Article...
Wallace.TL
3:40 10 Dec '04  
Hi,

The only suggestion that I could give you would be for it to utilize CodeDOM to generate code in other languages. Doing so would widen your audience base and allow this tool to benefit those of us who prefer C++ and Visual Basic as well.


Something like DALMaker which generates business class objects using CodeDOM for VB, CSharp, and J# developers.

I may be able to assist you in that regard if need me to. Thanks.

You can find Dalmaker listed here: http://www.windowsforms.net/ControlGallery/ControlDetail.aspx?Control=293&tabindex=10[^]

TL Wallace
http://www.arkitechebc.com
GeneralRe: Great Article...
Nirosh
17:40 12 Dec '04  
Hi,

Yes I am on.. let's do this... in the same time I guess we should think beyond this margin and find a better solution for developer.. I have some ideas.. let me have your personel email address..



L.W.C. Nirosh,
Software Engineer,
TextCENTRIC Technology,
Colombo,
Sri Lanka.
GeneralGood to learn but ...
Pritam Pal
19:06 7 Dec '04  
Nice article. But then this is already a crowded market. If I ignore the ORM software that is available, you still have likes of LLBLGen, Data Tier Generator to name a few.



P Pal


Last Updated 7 Dec 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010