Entity Framework & SQL Server CE - Underlying Provider Failed On Open - c#

I am building an application for internal use by my organization. It connects to a SQL Server CE database stored on our data server. The program works fine on my machine, but whenever I try to deploy it to another user, I received the following error:
An exception occurred while initializing the database. See the InnerException for details.
at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
at System.Data.Entity.Internal.LazyInternalContext.b__4(InternalContext c)
at System.Data.Entity.Internal.RetryAction1.PerformAction(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action1 action)
at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
at System.Data.Entity.Internal.Linq.InternalSet1.Initialize()
at System.Data.Entity.Internal.Linq.InternalSet1.GetEnumerator()
at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.IEnumerable.GetEnumerator()
at System.Data.Entity.QueryableExtensions.Load(IQueryable source)
at RunBKSales.Edit_Menu.Window_Loaded(Object sender, RoutedEventArgs e)
The underlying provider failed on Open.
The last line should be the InnerException. This is the code that throws the error:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
try
{
dbContext.Combos.Load();
dbContext.Products.Load();
dbContext.Stores.Load();
comboDataGrid.DataContext = dbContext.Combos.Local;
productDataGrid.DataContext = dbContext.Products.ToList();
storeDataGrid.DataContext = dbContext.Stores.ToList();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message + " " + ex.StackTrace);
System.IO.File.AppendAllText(LOG_FILE, String.Format("{0} \t {1} {2} {3}", DateTime.Now.ToShortDateString(), ex.Message, ex.StackTrace, ex.InnerException.Message) + System.Environment.NewLine);
}
}
The "Data Source" of the connection string is an UNC path to the .sdf database file.
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>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<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" />
<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>
<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>
<connectionStrings>
<add name="BKSalesModel"
connectionString="Data Source=\\FULL\UNC\PATH\db.sdf;Persist Security Info=False;"
providerName="System.Data.SqlServerCe.4.0" />
</connectionStrings>
</configuration>
Again, it works fines on my machine, so I am struggling with debugging it. Any advice would be appreciated.

Look at the Inner Exception of the "inner Exception" for the root cause error message!
You cannot use SQL Compact across a LAN, it is a single machine database (you can have several processes on the same machine use the same database located on a local disk, though)
For sharing data across a LAN you should use SQL Server Express

Related

How can I change path to my DB file on App.config?

I am trying to use sql server mdf file in winForm using entity framwork 6, I do not want to install SQL Server in user's computer to use my winform application.
For this sake I added new ADO.NET entity model and choose sql database file,
now I am trying to access mdf file (which is in debug folder of my project) from App.config connection string
my Connection string is
<add name="miosystem_halqaEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string='data source=TOFIQ;attachdbfilename="C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\miosystem_halqa.mdf";integrated security=True;MultipleActiveResultSets=True;App=EntityFramework'" providerName="System.Data.EntityClient" />
and App.config is
<?xml version="1.0" encoding="utf-8"?>
<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>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<connectionStrings>
<add name="miosystem_halqaEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string='data source=TOFIQ;attachdbfilename="C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\miosystem_halqa.mdf";integrated security=True;MultipleActiveResultSets=True;App=EntityFramework'" providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
The code is below for testing the connection
miosystem_halqaEntities db = new miosystem_halqaEntities();
private void Form1_Load(object sender, EventArgs e)
{
var j = db.ms_user.Where(x => x.user_id > 0).Select(x=>x.user_fname).ToList();
for (int i = 0; i < j.Count; i++)
{
label1.Text += j[i].ToString() + "\r";
}
}
I tried using ~ in my connection string but get the error
The underlying provider failed on Open.
<add name="miosystem_halqaEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string='data source=TOFIQ;attachdbfilename="~\miosystem_halqa.mdf";integrated security=True;MultipleActiveResultSets=True;App=EntityFramework'" providerName="System.Data.EntityClient" />
What I am missing in connection string ? how can i use relative path etc
From a relative path point of view, if the mdf file is in the debug folder of your project then you shouldn't need to specifiy a path in the connection string because your code will be running from that location. Try removing the ~\ from the connection string leaving just the filename.
However, even if the path is correct I'm not sure it's going to work anyway because the database instance TOFIQ referenced in the Data Source isn't going to exist on your client's machine. As Panagiotis said, I think you will need SQL Server Express on the client machine or host the file on a server that has SQL Server installed that the client has access to.

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>

Manually opening an EntityConnection to SQLite database causes ProviderIncompatibleException

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.

Categories