No Entity Framework provider found exception with dotConnect 5.1.36 and EF 6.0.1 Code-First

Discussion of open issues, suggestions and bugs regarding ADO.NET provider for SQLite
Post Reply
bairog
Posts: 120
Joined: Mon 29 Apr 2013 09:05

No Entity Framework provider found exception with dotConnect 5.1.36 and EF 6.0.1 Code-First

Post by bairog » Thu 14 Nov 2013 07:08

Hello.
I'm using dotConnect for SQLite 5.1.26 with Entity Framework 6.0.1 Code-First
I've tried to apply Code-based Provider Registration Example to my code like that

Code: Select all

[DbConfigurationType(typeof(Devart.Data.SQLite.Entity.SQLiteEntityProviderServicesConfiguration))]
public class MyContext : DbContext 
{
   // ...
}
But while accessing data I receive exception
No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlClient'. Make sure the provider is registered in the 'entityFramework' section of the application config file
It's strange that EF is still looking for 'System.Data.SqlClient'..

I've tried second described approach

Code: Select all

static MyContext()
        {
            DbConfiguration.SetConfiguration(new Devart.Data.SQLite.Entity.SQLiteEntityProviderServicesConfiguration());
        }
but failed again with the same error..

So where I'm mistaking?

Here is my sample code:
http://yadi.sk/d/U69J3nEjCfCAa

INFO:
SQLite Code First
Entity Framework 6.0.1
VS 2010 SP1 (.NET 4.0)
dotConnect for SQLite 5.1.26
Windows 7 SP1 32bit

UPDATE With today's release 5.1.36 the result is the same..

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

Re: No Entity Framework provider found exception with dotConnect 5.1.36 and EF 6.0.1 Code-First

Post by Shalex » Thu 14 Nov 2013 14:44

Entity Framework requires the provider name to be specified explicitly:

a) add the new constuctor to MyContext in Entities.cs

Code: Select all

    public MyContext(System.Data.Common.DbConnection conn, bool contextOwnsConnection)
            : base(conn, contextOwnsConnection) {
    }
b) use it in Form1.cs

Code: Select all

    var connection = System.Data.Common.DbProviderFactories.GetFactory("Devart.Data.SQLite").CreateConnection();
    connection.ConnectionString = "Data Source=d:\\Database.db";
    var _context = new MyContext(connection, true);
    ((IObjectContextAdapter)_context).ObjectContext.Connection.Open();
As an alternative way, use Config File Registration.

bairog
Posts: 120
Joined: Mon 29 Apr 2013 09:05

Re: No Entity Framework provider found exception with dotConnect 5.1.36 and EF 6.0.1 Code-First

Post by bairog » Thu 14 Nov 2013 15:18

Shalex wrote:As an alternative way, use Config File Registration.
Due to my program limitations I have to use Code-based Registration only.
Shalex wrote:Entity Framework requires the provider name to be specified explicitly
Do you mean Entity Framework starting from version 6 requires the provider name to be specified explicitly?
Is it a necessary part of new configuration scheme introduced in EF6?

Because in EF4 and EF5 connection creation logic (described in your answer) was encapsulated in SQLiteConnectionFactory class with CreateConnection method (this class and method was btw taken from one of Devart tutorial).

Code: Select all

private class SQLiteConnectionFactory : IDbConnectionFactory
        {
            public DbConnection CreateConnection(string connectionString)
            {
                if (String.IsNullOrEmpty(connectionString))
                    throw new ArgumentNullException("connectionString");

                DbProviderFactory sqliteProviderFactory = DbProviderFactories.GetFactory("Devart.Data.SQLite");
                if (sqliteProviderFactory == null)
                    throw new InvalidOperationException(String.Format("The '{0}' provider is not registered on the local machine.", DbAccess.invariantProviderName));

                DbConnection connection = sqliteProviderFactory.CreateConnection();
                connection.ConnectionString = connectionString;

                return connection;
            }
        }
After that in EF4 and EF5 I've used

Code: Select all

Database.DefaultConnectionFactory = new SQLiteConnectionFactory();
But Database.DefaultConnectionFactory is marked as deprecated in EF6 with warning that
"The default connection factory should be set in the config file or using the DbConfiguration class (See http://go.microsoft.com/fwlink/?LinkId=260883)"
As I can see SQLiteEntityProviderServicesConfiguration is a descendant of DbConfiguration class.
So why all this connection creation logic is not encapsulated in this class like Microsoft suggests?
I mean setting the default way for converting connection string to proper provider's connection - this will allow to create DbContext with only a connection string as it was before.
Am I missing something?

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

Re: No Entity Framework provider found exception with dotConnect 5.1.36 and EF 6.0.1 Code-First

Post by Shalex » Fri 15 Nov 2013 14:25

bairog wrote:Database.DefaultConnectionFactory is marked as deprecated
You can ignore the warning.
bairog wrote:As I can see SQLiteEntityProviderServicesConfiguration is a descendant of DbConfiguration class.
So why all this connection creation logic is not encapsulated in this class like Microsoft suggests?
We do not set a default connection factory in SQLiteEntityProviderServicesConfiguration because this setting would affect all the code within current application domain.

bairog
Posts: 120
Joined: Mon 29 Apr 2013 09:05

Re: No Entity Framework provider found exception with dotConnect 5.1.36 and EF 6.0.1 Code-First

Post by bairog » Sat 16 Nov 2013 11:06

Shalex wrote:We do not set a default connection factory in SQLiteEntityProviderServicesConfiguration because this setting would affect all the code within current application domain.
For my application it's normal.
So instead of specifying provider explicitly every time DbContextis created I prefer using

Code: Select all

Database.DefaultConnectionFactory = new SQLiteConnectionFactory();
Thank you, my code is working now.

bairog
Posts: 120
Joined: Mon 29 Apr 2013 09:05

Re: No Entity Framework provider found exception with dotConnect 5.1.36 and EF 6.0.1 Code-First

Post by bairog » Fri 17 Jan 2014 05:25

Hello again.
Looks like your solution is not working when I use Code-First automatic migrations

Code: Select all

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, SysTypesDbContextMigrationConfiguration>());
instead of

Code: Select all

Database.SetInitializer(new CreateDatabaseIfNotExist<MyContext>());
I have no database existing.
And when I run my code I receive runtime exception
Keyword not supported: 'failifmissing'
Tested with the latest dotConnect for SQLite 5.1.80

ONCE AGAIN: Due to my program limitation I can't use provider registration via config file, that's why I perform all actions in code.


Here is my sample code:
http://yadi.sk/d/we4snyANGDCoS

INFO:
SQLite Code First
Entity Framework 6.0.1
VS 2010 SP1 (.NET 4.0)
dotConnect for SQLite 5.1.80
Windows 7 SP1 32bit

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

Re: No Entity Framework provider found exception with dotConnect 5.1.36 and EF 6.0.1 Code-First

Post by Shalex » Fri 17 Jan 2014 15:05

Please implement the following changes in your code because EF Migrations with your current code creates an additional context with a default DbConnectionFactory (System.Data.SqlClient.SqlConnectionFactory):

1. In Entities.cs replace

Code: Select all

        public MyContext()
            : base("Data Source=d:\\Database.db;FailIfMissing=false")
        {
        }
with

Code: Select all

        public MyContext()
            : base(CreateConnection(), true)
        {
        }
        private static System.Data.Common.DbConnection CreateConnection() {

            var connection = System.Data.Common.DbProviderFactories.GetFactory("Devart.Data.SQLite").CreateConnection();
            connection.ConnectionString = "Data Source=d:\\Database.db;FailIfMissing=false";
            return connection;
        }
2. In Form1.cs replace

Code: Select all

            var connection = DbProviderFactories.GetFactory("Devart.Data.SQLite").CreateConnection();
            connection.ConnectionString = "Data Source=d:\\Database.db;FailIfMissing=false";
            var _context = new MyContext(connection, true);
with

Code: Select all

            var _context = new MyContext();

bairog
Posts: 120
Joined: Mon 29 Apr 2013 09:05

Re: No Entity Framework provider found exception with dotConnect 5.1.36 and EF 6.0.1 Code-First

Post by bairog » Fri 17 Jan 2014 17:17

Thank you.
Now I see what I've missed.

Post Reply