Page 1 of 1

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

Posted: Thu 14 Nov 2013 07:08
by bairog
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..

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

Posted: Thu 14 Nov 2013 14:44
by Shalex
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.

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

Posted: Thu 14 Nov 2013 15:18
by bairog
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?

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

Posted: Fri 15 Nov 2013 14:25
by Shalex
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.

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

Posted: Sat 16 Nov 2013 11:06
by bairog
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.

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

Posted: Fri 17 Jan 2014 05:25
by bairog
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

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

Posted: Fri 17 Jan 2014 15:05
by Shalex
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();

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

Posted: Fri 17 Jan 2014 17:17
by bairog
Thank you.
Now I see what I've missed.