Manually opening an EntityConnection to SQLite database causes ProviderIncompatibleException - c#

For integration testing purposes I'd like to manually create and open an EntityConnection in the test fixture set up. This fails with the following exception when calling the Open() method:
System.Data.ProviderIncompatibleException : A null was returned after calling the 'GetService' method on a store provider instance of type 'System.Data.SQLite.EF6.SQLiteProviderFactory'. The store provider might not be functioning correctly.
I'm using the same connection string which is also used when EF takes care about connection opening. If I run the same test suite with automatic connection handling by EF it works.
...
[TestFixtureSetUp]
public void FixtureSetUp()
{
// Setup database
// Setup data access
...
var ec = new EntityConnection([ConnectionString]);
ec.StoreConnection.Open(); --> WORKS!!
ec.Open(); -> Throws
}
...
The connection string looks like the following:
metadata=res://*/Test.TestModel.csdl|res://*/Test.TestModel.ssdl|res://*/Test.TestModel.msl;provider=System.Data.SQLite;provider connection string="data source=C:\Test\tmp4C80.tmp;read only=False;pooling=False;failifmissing=True;synchronous=Full;datetimekind=Utc;enlist=True;setdefaults=False;datetimeformat=ISO8601;journal mode=Off;cache size=4194304"
The app.config for the NUnit assembly is the following
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SQLite"
type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</entityFramework>
<!-- Register protable database data providers -->
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite" />
<add name="SQLite Data Provider" invariant="System.Data.SQLite"
description=".Net Framework Data Provider for SQLite"
type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6, Version=1.0.94.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
</DbProviderFactories>
</system.data>
</configuration>
Beside NUnit for testing, I'm using Entity Framework 6.1.1 and System.Data.SQLite 1.0.94.0.
Edit: The strange thing is that opening the store connection of the provided entity connection manually works...

I found out that I used the EntityConnection from System.Data.Entity instead of the EntityFramework assembly.

Related

SQLite & Entity Framework 6 "The underlying data provider failed to open"

When my Winforms application reaches the first Entity Framework data "request" I get the following error.
Message: The underlying provider failed to open.
InnerException: Data source cannot be empty.
My connection string is being built dynamically to cater for the user's %appdata% directory path. I am building it at first runtime and updating the app.config with the connection string once it is built. The code that handles this is below:
public void ConstructEntityFrameworkConnectionString(string dbFileName)
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.ConnectionStrings.ConnectionStrings["RemManagerDBEntities"] == null)
{
// Specify the provider name, server and database.
var provider = "System.Data.SQLite.EF6";
var providerName = "System.Data.EntityClient";
var attacheddbfilename = dbFileName;
// Initialize the connection string builder for the underlying provider.
SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder {
AttachDBFilename = attacheddbfilename,
IntegratedSecurity = true,
MultipleActiveResultSets = true,
ConnectTimeout = 30,
ApplicationName = "RemManagerDBEntities"
};
// Build the SqlConnection connection string.
string providerString = sqlBuilder.ToString();
// Initialize the EntityConnectionStringBuilder.
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder {
Provider = provider,
ProviderConnectionString = providerString,
Metadata = #"res://*/EntityFramework.RemManagerDBModel.csdl|res://*/EntityFramework.RemManagerDBModel.ssdl|res://*/EntityFramework.RemManagerDBModel.msl"
};
var cs = new ConnectionStringSettings("RemManagerDBEntities", entityBuilder.ConnectionString, providerName);
if (config.ConnectionStrings.ConnectionStrings["RemManagerDBEntities"] == null)
{
config.ConnectionStrings.ConnectionStrings.Add(cs);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("connectionStrings");
}
}
}
An example connection string that it creates:
metadata=res://*/EntityFramework.RemManagerDBModel.csdl|res://*/EntityFramework.RemManagerDBModel.ssdl|res://*/EntityFramework.RemManagerDBModel.msl; provider=System.Data.SQLite.EF6; provider connection string="AttachDbFilename=C:\Users\MacbookPro\AppData\Roaming\RemManager\Datasource\RemManagerDB.db; Integrated Security=True; MultipleActiveResultSets=True; Connect Timeout=30; Application Name=RemManagerDBEntities"
The method is called as part of the main method in the program.cs file.
static void Main()
{
var conController = new ConnectionController();
conController.ConstructEntityFrameworkConnectionString($"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\RemManager\\Datasource\\RemManagerDB.db");
// Start the application
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new RemManager());
}
I've got the following NuGet packages installed:
Entity Framework 6
System.Data.SQLite
System.Data.SQLite.EF6
System.Data.SQLite.Core
System.Data.SQLite.Linq
Initially I have based the setup procedure from the following site with an amendment made by the second link shown.
https://www.codeproject.com/Tips/1056400/Setting-up-SQLite-and-Entity-Framework-Code-First
https://github.com/ErikEJ/SqlCeToolbox/wiki/EF6-workflow-with-SQLite-DDEX-provider
Below is an example of the calls that I am making to the database via entity framework. When stepping through the code the exception begins on the db.tblGroups.Select line.
public class GroupController : IGroup
{
public List<tblGroup> SelectAllGroups()
{
using (var db = new RemManagerDBEntities())
{
return db.tblGroups.Select(g => g).ToList();
}
}
...
}
The final piece of the puzzle is the app.config. The current config is shown below.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<!-- See Datasource.ConnectionController for the connection string builder.-->
</connectionStrings>
<entityFramework>
<providers>
<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</entityFramework>
<appSettings>
<add key="databaseFilePath" value="" />
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
</providers>
</roleManager>
</system.web>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite.EF6" />
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
<add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
</DbProviderFactories>
</system.data>
</configuration>
For what else it is worth, entity framework is working from a database first configuration. I am also running Entity Framework 6.2 and SQLite 1.0.106.0.
I've tried my best to find a valid solution on other sites that caters for the fact that I am combining Entity Framework and SQLite, but I haven't been able to come up with much. When I take the SQLite out of the equation, I still haven't been able to come up with much. One of the better questions I had found was here, but I am already doing what the suggested answer recommends.
I had a similar problem earlier, except with localdb. The application has been working previously on the localdb, however this issue has started since I have been endeavouring toward making the application more self contained and user friendly (e.g. not needing to modify the exe.config manually once installed).
Any suggestions would be greatly appreciated.
You cannot use a SqlConnectionStringBuilder with SQLite, use SQLiteConnectionStringBuilder instead, and set the DataSource property to the database file name

Cannot set ProviderService in configuration

I am trying to move my app.config ef settings to code.
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
<parameters>
<parameter value="System.Data.SqlServerCe.4.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SqlServerCe.4.0"
type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SqlServerCe.4.0" />
<add name="Microsoft SQL Server Compact Data Provider 4.0"
invariant="System.Data.SqlServerCe.4.0"
description=".NET Framework Data Provider for Microsoft SQL Server Compact"
type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
</DbProviderFactories>
</system.data>
</configuration>
Currently all I was able to set is the defaultConnectionFactory:
public class SqlServerCompactConfiguration : DbConfiguration
{
public SqlServerCompactConfiguration()
{
SetDefaultConnectionFactory(new System.Data.Entity.Infrastructure.SqlCeConnectionFactory("System.Data.SqlServerCe.4.0"));
SetProviderFactory("System.Data.SqlServerCe.4.0", new System.Data.SqlServerCe.SqlCeProviderFactory());
SetProviderServices("System.Data.SqlServerCe.4.0", new System.Data.Entity.SqlServerCompact.SqlCeProviderServices());
SetProviderServices("System.Data.SqlClient", new System.Data.Entity.SqlServer.SqlProviderServices());
}
}
For the last 2 lines I am getting the following error:
'SqlCeProviderServices' does not contain a constructor that takes 0 arguments'
I got no idea what to add here... Intellisense is showing nothing an so is the class when I use GoToDefinition there is no constructor...
Usually such service classes are implemented as singletons.
For instance, SqlProviderServices class contains the following:
//
// Summary:
// The Singleton instance of the SqlProviderServices type.
public static SqlProviderServices Instance { get; }
I can't check now, but I'm pretty sure SqlProviderService class has something similar.

MySql EF6 with IdentityDbContext

I try to use MS Identity with an MySql Databse and Code-First.
My DbContext Class:
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class TestDbContext : IdentityDbContext<ApplicationUser>
{
public TestDbContext()
{
}
public TestDbContext(string cnString)
: base(cnString)
{
}
}
My App Config:
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="TestDbContext" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;port=3306;database=test;uid=root;password=root"/>
</connectionStrings>
<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
</defaultConnectionFactory>
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
</configuration>
If i use the normal DbContext its works with Code-First Migrations. But if i change to IdentityDbContext and i try to "Update-Database" i get the following Error:
Failed to set Database.DefaultConnectionFactory to an instance of the
'System.Data.Entity.Infrastructure.LocalDbConnectionFactory,
EntityFramework' type as specified in the application configuration.
See inner exception for details.
How can i get MS Identity to work with MySql?
Ok i have change the DefaultConnectionFactory to
<defaultConnectionFactory type="MySql.Data.Entity.MySqlConnectionFactory, MySql.Data.Entity.EF6" />
but now i get another Error:
Format of the initialization string does not conform to specification starting at index 0.
Ok i get the Database Connection to work but the Identity Tables such as aspnetuser won't create automaticly.

SQLite: Entity Framework 6 - Wrong DbProviderFactory

I'm going bonkers with this.
I have a standard C# console application, with EF 6.1.3 and SQLite 1.0.97.0. I've set up my app.config to connect to the SQLite database using standard ADO, which works:
static void StandardConnection()
{
try
{
SQLiteConnection db = new SQLiteConnection(ConfigurationManager.ConnectionStrings["StudioContext"].ConnectionString);
db.Open();
Console.WriteLine("Connected");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
But for the love of me, I can't get EF to connect to this database. I have tried every single solution I could read up on, but every time I try to connect, I find the DBProviderFactory always points to {System.Data.SqlClient.SqlClientFactory}. It is driving me insane.
Following, my DbContext class:
public class SqliteContext: DbContext
{
public SqliteContext()
: base(ConfigurationManager.ConnectionStrings["StudioContext"].ConnectionString)
{
Database.SetInitializer<SqliteContext>(null);
}
}
I don't want code first enabled, so disabled it here as this is off an existing application, being ported from PHP to C# and we have to work with the database as it is currently.
The code that's trying to connect:
static void EntityFrameworkConnection()
{
try
{
using (var db = new SqliteContext())
{
if (db.Database.Connection.State == System.Data.ConnectionState.Closed)
{
db.Database.Connection.Open();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Very basic, open an instance of the context, check the state and connect if closed, this step is not required as I understand that EF will open the connection, if closed, when doing something like a save, for example, I'm just trying to get the DB to connect.
My app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="StudioContext" connectionString="Data Source=.\studio.db" providerName="System.Data.SQLite" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6, Version=1.0.97.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6, Version=1.0.97.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite" />
<add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.97.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
<remove invariant="System.Data.SQLite.EF6" />
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6, Version=1.0.97.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
</DbProviderFactories>
</system.data>

How to use DotConnect For PostgreSQL and entity framework code first

I am trying to use POstgreSQL database in my project.
I would like to learn code first developement..
I download dotconnect for PostgreSql (trial version) and I added Devart.Data.PostgreSql dll to my references. Then, I added those lines in my app.copnfig
<connectionStrings>
<add name="SchoolDBConnectionString" connectionString="Server=localhost;Port = 5432;Database=MyDataBase;user Id=postgres;password=*****" providerName="Devart.Data.PostgreSql" />
</connectionStrings>
<system.data>
<DbProviderFactories>
<remove invariant="Devart.Data.PostgreSql" />
<add name="dotConnect for PostgreSQL" invariant="Devart.Data.PostgreSql" description="Devart dotConnect for PostgreSQL" type="Devart.Data.PostgreSql.PgSqlProviderFactory, Devart.Data.PostgreSql, Version= 6.8.333.0, Culture=neutral, PublicKeyToken=09af7300eec23701" />
</DbProviderFactories>
</system.data>
</configuration>
WHen I execute my application i have this exeption :
An error occurred while getting provider information from the database. This can be caused by Entity Framework using an incorrect connection string. Check the inner exceptions for details and ensure that the connection string is correct.
Try to add this (Not tested)
<provider invariantName="Devart.Data.PostgreSql" type="Devart.Data.PostgreSql.Entity.PgSqlEntityProviderServices,
Devart.Data.PostgreSql.Entity, Version=7.1.26.6, Culture=neutral, PublicKeyToken=09af7300eec23701" />
and
<entityFramework>
<providers>
<provider invariantName="Devart.Data.PostgreSql" type="Devart.Data.PostgreSql.Entity.PgSqlEntityProviderServices,
Devart.Data.PostgreSql.Entity, Version=7.1.26.6, Culture=neutral, PublicKeyToken=09af7300eec23701" />
</providers>
</entityFramework>
Note: Replace 7.1.26.6 with the actual assembly version.

Categories