DbProviderFactories

Discussion of open issues, suggestions and bugs regarding ADO.NET provider for SQLite
Post Reply
mspeyer
Posts: 1
Joined: Fri 09 Apr 2010 23:42

DbProviderFactories

Post by mspeyer » Fri 09 Apr 2010 23:52

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

StanislavK
Devart Team
Posts: 1710
Joined: Thu 03 Dec 2009 10:48

Post by StanislavK » Mon 12 Apr 2010 11:49

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.

jrlewis
Posts: 8
Joined: Fri 18 Nov 2011 15:29

Post by jrlewis » Thu 22 Dec 2011 23:24

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

 
    
      
      
    
  

StanislavK
Devart Team
Posts: 1710
Joined: Thu 03 Dec 2009 10:48

Post by StanislavK » Thu 29 Dec 2011 16:57

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.

jrlewis
Posts: 8
Joined: Fri 18 Nov 2011 15:29

Post by jrlewis » Thu 05 Jan 2012 14:20

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.

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Post by Shalex » Thu 12 Jan 2012 11:55

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).

jrlewis
Posts: 8
Joined: Fri 18 Nov 2011 15:29

Post by jrlewis » Thu 12 Jan 2012 14:27

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.

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Post by Shalex » Thu 12 Jan 2012 16:25

According to MSDN, the provider factory class should be specified with the fully qualified name: http://msdn.microsoft.com/en-us/library/dd0w4a2z.aspx.

jrlewis
Posts: 8
Joined: Fri 18 Nov 2011 15:29

Post by jrlewis » Thu 12 Jan 2012 17:38

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.

Post Reply