Question

I am using ADO.NET interfaces to create a database independent program. The factory takes in a provider name and returns vendor specific objects which implement the ADO interface. This is great.

But I can't find a factory for the flag which identifies a parameter.

string paramName = "@foo"; //flag "@" for sql server

string paramName = ":foo"; //flag ":" for oracle

Question: Does ADO.NET provide a factory method to obtain the flag?
I could roll my own separate factory for this, but it would limit me to a predefined list of providers; defeating much of the benefit of the provider factory.

Was it helpful?

Solution

Unfortunately, the DbProviderFactory mechanism is very poorly designed IMHO. The mechanism itself is not extensible, all the interesting classes are sealed (SqlClientFactory, etc.), the configuration in the .config file is not extensible either.

One simple solution is to build an extension class, like this:

public static class DbProviderFactoryExtensions
{
    public static DbParameter CreateParameter(this DbProviderFactory factory, string name)
    {
        DbParameter parameter = factory.CreateParameter();
        if (factory.GetType().FullName.IndexOf("sqlclient", StringComparison.OrdinalIgnoreCase) >= 0)
        {
            name = "@" + name;
        }
        else if (factory.GetType().FullName.IndexOf("oracle", StringComparison.OrdinalIgnoreCase) >= 0)
        {
            name = ":" + name;
        } // etc...
        parameter.ParameterName = name;
        return parameter;
    }
}

It's not very smart, but you can do this in your code:

    DbProviderFactory factory = DbProviderFactories.GetFactory("MyDb");
    DbParameter parameter = factory.CreateParameter("myParam");
    // parameter.ParameterName will be @myParam if SQL, etc.

Or you could also recreate your own system. It's not very complicated, and can be worth it if you need other variable items per type of database.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top