Page 1 of 1

DbProviderFactories

Posted: Fri 09 Apr 2010 23:52
by mspeyer
Hi,

I would like to know how I can best use the provider pattern with dotConnect for SQLite. I cannot see a Factory method in Devart.Data.SQLite which would allow me to define in the web.config file:

Code: Select all

  
  
  
  
and then use

Code: Select all

   DbProviderFactory fact = DbProviderFactories.GetFactory("Devart.Data.SQLite");
      using (DbConnection cnn = fact.CreateConnection())
      {
       ...
       }
How would I do this in dotConnect for SQLite?

Thanks,

Marc

Posted: Mon 12 Apr 2010 11:49
by StanislavK
Such method should work with dotConnect for SQLite. For example, I have the following entry in my machine.config file:

Code: Select all

...
   
...
and the following code successfully creates a SQLiteConnection object:

Code: Select all

DbProviderFactory fact = DbProviderFactories.GetFactory("Devart.Data.SQLite");
DbConnection con = fact.CreateConnection();
Please tell us if you encounter errors with this.

Posted: Thu 22 Dec 2011 23:24
by jrlewis
Is it possible to use a version indpendent declaration for the provider factory so it will just load whatever provider is located in the app folder. I end up getting a NullReferenceException when I try to access the db if I use the declaration below.

Code: Select all

 
    
      
      
    
  

Posted: Thu 29 Dec 2011 16:57
by StanislavK
Sorry for the delay. According to MSDN, the provider factory class should be specified with the fully qualified name:
http://msdn.microsoft.com/en-us/library/dd0w4a2z.aspx

Could you please specify the purpose of using the partial name of the factory class? If, for example, you are going to do this on a developer machine where dotConnect for SQLite is installed, it should be sufficient to specify any version of dotConnect for SQLite, because the policy files will redirect to the latest one.

Posted: Thu 05 Jan 2012 14:20
by jrlewis
It does list the column name as the AssemblyQualifiedName for the column returned by the GetFactoryClasses() method, but if you look at the description it reads "Fully qualified name of the factory class, which contains enough information to instantiate the object." If the provider is in the working directory and it is specified with "FullName,AssemblyName" then that should be enough information to instantiate the object. This is a feature that the System.Data.SQLite provider has. This is beneficial for several reasons.

A recent update to dotConnect for SQLite fixed an issue with one project and broke another. In this case the policy files are working against me. Uninstalling the provider and just pointing to the correct version of the dll's in the working directory doesn't work either as it never checks the working directory. At this point I have 2 projects that need 2 different versions of the provider on the same machine. It can't be done as far as I can tell. So each project gets its own development machine for now until the issue is fixed.

For deployment and updates for the shipping versions of these projects I don't want to have to deal with unregistering/registering the provider from the GAC when a new provider is required as part of an update or at installation. I just want to drop the required assemblies into the working directory and leave the config file alone if at all possible. Being able to specify a non-version specific provider and it only checking in the same directory as the assembly trying to access it would be the preferred method. A version specific declaration would be sufficient if the working directory was the first location that was checked. As far as I can tell the working directory is never checked.

Posted: Thu 12 Jan 2012 11:55
by Shalex
jrlewis wrote:It does list the column name as the AssemblyQualifiedName for the column returned by the GetFactoryClasses() method, but if you look at the description it reads "Fully qualified name of the factory class, which contains enough information to instantiate the object." If the provider is in the working directory and it is specified with "FullName,AssemblyName" then that should be enough information to instantiate the object.
Please refer to the example in the table with the mentioned definition: "System.Data.SqlClient.SqlClientFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" (there are Version and Culture as well).

http://social.msdn.microsoft.com/Forums ... 302c1db13/:
"if you were trying to load a strongly-named assembly you would have specified the strong name. Since you only provided a weak name, it would be an error to give you the strongly-named assembly because if you wanted the strongly named one you would have asked for it."
CLR looks for strongly-named assemblies in the following way: GAC first, then local (the folder in which your application is located).
jrlewis wrote:Uninstalling the provider and just pointing to the correct version of the dll's in the working directory doesn't work either as it never checks the working directory.
This should work.
1. Place the Devart.* assemblies in the folder in which your application is located.
2. Make sure there are no policy.*.Devart.* files in your GAC.
3. Specify the exact text of the error you are getting.
jrlewis wrote:At this point I have 2 projects that need 2 different versions of the provider on the same machine.
This is possible. Just specify fully qualified name of dotConnect for SQLite in your App.config and remove policy.*.Devart.* files from your GAC (different versions of Devart assemblies can be located either in GAC, or in bin folders).

Posted: Thu 12 Jan 2012 14:27
by jrlewis
Well I guess I should be eating some crow. Best I can tell at some point the "copy to local" for the referenced dll's got set to False (I had set it to True) so they were never making into the working directory when I was attempting to use the local version. Works just fine. Would still prefer the ability to use a non-version specific declaration for the dbproviderfactory in the configuration as is provided by the system.data.sqlite provider.

Posted: Thu 12 Jan 2012 16:25
by Shalex
According to MSDN, the provider factory class should be specified with the fully qualified name: http://msdn.microsoft.com/en-us/library/dd0w4a2z.aspx.

Posted: Thu 12 Jan 2012 17:38
by jrlewis
See my previous comment. The provider is being loaded via reflection at runtime. A non-specific version is enough information to instantiate the provider. I don't see how providing this hurts you at all as long as you are supporting using an assembly qualified name as well. This is something that the SQLite factory allows. Unfortunately the only thing lacking with the current System.Data.SQLite provider is code first support where a database doesn't already exist. I'm sure that will change in the future.