tags:

views:

62

answers:

1

Hi All, I'm working on a database factory pattern for an application which should support Sql Server and Oracle. I've an abstract classes with all the Sql Queries for the application. I've implemented the abstract class in two classes: SqlServerClass and OracleClass. Based on the connection string defined in the configuration file, the application creates an instance of the corresponding class and get the Sql queries for the database.

    public abstract class ProviderFactory 
    {
        public abstract string GetCustomersSql();
        public abstract string GetCustomersByIdSql();
        public abstract string GetUsersSql();
        public abstract string GetUsersByIdSql();
    }

    public class OracleClass : ProviderFactory
    {
        public override string GetCustomersSql()
        {
            // return sql query for Oracle
        }
        // other methods
    }
    public class SqlServerClass : ProviderFactory
    {
        public override string GetCustomersSql()
        {
            // return sql query for Sql Server
        }
        // other methods
    }

Now my question is, Is there a way to group these sql queries in the abstract class so that one can easily identify the sql queries used for particular functionality. For example, Can I group all Customers related queries and Users related queries so that when I refer them, it would be like....

ProviderFactory instance;
// create an instance
instance.Customers.GetCustomersSql();

Is what I'm doing here a valid approach? Please suggest. Thank you.

+2  A: 

I would strongly recommend using an ORM such as NHibernate. It supports both SQL Server and Oracle and abstracts away the differences between the two.

By that I mean you only have to write the query once in a format NHibernate understands and it will translate that to versions that SQL Server and Oracle understand.

If you want to continue down your current path what you can do is create what I'd call a query directory:

public interface IQueryDirectory
{
    ICustomerQueries Customer { get; }
    IUserQueries User { get; }
}

public interface ICustomerQueries
{
   string Customers { get; }
   string CustomersById { get; }
}

public interface IUserQueries
{
   string Users { get; }
   string UsersById { get; }
}

Example implementation:

public abstract class QueryDirectory : IQueryDirectory
{
    private ICustomerQueries customer;
    private IUserQueries user;

    public ICustomerQueries Customer 
    { 
        get { return customer; }
    }

    public IUserQueries User
    {
        get { return user; }
    }

    protected QueryDirectory(ICustomerQueries customer, IUserQueries user)
    {
        this.customer = customer;
        this.user = user;
    }
}

public class SqlServerQueryDirectory : QueryDirectory
{
    public SqlServerQueryDirectory(SqlServerCustomerQueries customer,
        SqlServerUserQueries user) : base(customer, user) {}
}

public class SqlServerCustomerQueries : ICustomerQueries
{
   public string Customers 
   {
       get "some sql";
   }

   public string CustomersById 
   { 
       get "some sql";
   }
}

Then you can implement the directories seperately for each database. But honestly, I really, really, really recommend using an ORM instead.

Garry Shutler
Hi Garry, Thanks for the response. I like the ORM approach, but I use some complicated queries like recursive queries, common table expressions, etc. Can I still use NHibernate to support these queries? Also, in the original approach, how can I implement the methods of the interface in the OracleClass and SqlServerClass classes? Thanks a lot.
You may not be able to use NHibernate for really complex queries, but it definitely capable of doing 95% of the queries in a regular project. By making that 95% easy to maintain between databases you have less to worry about. NHibernate still lets you make direct calls to the database when you need to so you could use a per-database approach in the trickier areas whilst having the benefit of cross-database implementation everywhere else.
Garry Shutler
Thanks a lot Garry, That really helped a lot. The above code works perfectly. And also, I will now really consider using NHibernate.
No problem :)
Garry Shutler