I'm using EF 6 with a database-first approach and Oracle. However, on connecting, the following exception is thrown:
Unable to cast object of type 'Oracle.ManagedDataAccess.Client.OracleConnection' to type 'System.Data.SqlClient.SqlConnection'
I'm a little confused ...
My web.config looks actually right:
<configuration>
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
<section name="oracle.manageddataaccess.client"
type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.122.18.3, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</configSections>
<connectionStrings>
<add name="TestConnection"
providerName="System.Data.EntityClient"
connectionString="metadata=res://*/Model.Entities.PimEntities.csdl|res://*/Model.Entities.PimEntities.ssdl|res://*/Model.Entities.PimEntities.msl;provider=Oracle.ManagedDataAccess.Client;provider connection string="data source=TestDataSource;persist security info=True;user id=XXX;password=XXX"" />
</connectionStrings>
<system.data>
<DbProviderFactories>
<remove invariant="Oracle.DataAccess.Client" />
<remove invariant="Oracle.ManagedDataAccess.Client" />
<add name="ODP.NET, Managed Driver"
invariant="Oracle.ManagedDataAccess.Client"
description="Oracle Data Provider for .NET, Managed Driver"
type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.18.3, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
<entityFramework>
<defaultConnectionFactory type="Oracle.ManagedDataAccess.EntityFramework.OracleConnectionFactory, Oracle.ManagedDataAccess.EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="Oracle.ManagedDataAccess.Client"
type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.122.18.3, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</providers>
</entityFramework>
<oracle.manageddataaccess.client>
<version number="*">
<dataSources>
<dataSource alias="TestDataSource" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=TestServer.TestDomain.loc)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=TestService))) " />
</dataSources>
<settings>
<setting name="BindByName" value="true" />
</settings>
</version>
</oracle.manageddataaccess.client>
</configuration>
To be sure I checked my DbContext class:
public partial class TestEntities : DbContext
{
public DbSetProvider() : base("name=TestConnection")
{
}
}
Seems legit.
After hours of researching I just created a new web application, imported specific nuget packages and set up ef with code first approach without generating the .edmx file.
This works as intended.
The used web.config for the code first approach is the same like before, except:
<add name="TestConnection"
providerName="Oracle.ManagedDataAccess.Client"
connectionString="User Id=XXX;Password=XXX;Data Source=TestDataSource" />
Now I'm completely done.
Nothing changed except the providerName and of course the metadata information.
So my question is: why is Entity Framework trying to convert OracleConnection to SqlConnection?
Or how to fix my issue and using the database-first approach?
Excuse me for my imperfect English skills.
Thanks in advance.
According to the docs here, your connection string providerName should be the Oracle one:
providerName="Oracle.ManagedDataAccess.Client"
not the providerName="System.Data.EntityClient"
Related
App.config file:
<?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.7.2" />
</startup>
<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" />
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<add name="SQLiteConnection" providerName="System.Data.SQLite.EF6" connectionString="Data Source=C:\Users\wzz\source\repos\PutixinEditor\PutixinEditor\db.sqlite" />
</DbProviderFactories>
</system.data>
</configuration>
my dbContext:
class PutixinDbContext : DbContext
{
public PutixinDbContext() : base("SQLiteConnection")
{
Database.SetInitializer<PutixinDbContext>(null);
}
public DbSet<Category> Category { get; set; }
}
But when I context.SaveChanges(), error throw:
SqlException: Cannot open database "SQLiteConnection" requested by the login. The login failed.
Login failed for user 'DESKTOP-BR8U8NG\wzz'.
I am using Visual Studio 2019
Error: "System.Data.SqlClient.SqlException: Cannot open database "MyDatabase" requested by the login. The login failed.
Login failed for user 'MyComputer\myUser'."
The error is very misleading because in your case, it will happen even if the the user has full permissions to write to the file and directory in question, in your case directory C:\Users\wzz\source\repos\PutixinEditor\PutixinEditor\ and file C:\Users\wzz\source\repos\PutixinEditor\PutixinEditor\db.sqlite.
The name of the string parameter passed to the DBContext constructor is "nameOrConnectionString". You are not passing a connection string, but instead your provider name. You have no such connection string.
As per Microsofts documentation, since no such connection string is found, the name is passed to the DefaultConnectionFactory, which wants to connect to a MsSQL or SqlExpress database. This is probably where the "Login failed" message comes from.
However,there is no ConnectionFactory class in System.Data.Sqlite.EF6 (v4.0.30319) which you could use instead.
Here is what will work: Create and name a separate connection string:
<connectionStrings>
<add name="SQLiteConnection" connectionString="data source=C:\Users\wzz\source\repos\PutixinEditor\PutixinEditor\db.sqlite;foreign keys=true" providerName="System.Data.SQLite" />
</connectionStrings>
You also have to configure the corresponding ProviderFactory, or else you'll get an error about not finding the requested provider
(With the friendly message "The ADO.NET provider with invariant name 'System.Data.SQLite' is either not registered in the machine or application config file, or could not be loaded.").
The provider factory you need is System.Data.SQLite.SQLiteFactory (from the System.Data.SQLite assembly).
<DbProviderFactories>
<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>
Now your DbContext should work.
I got the same error when I misspelled the name of the connection string in the constructor of the DbContext. It was very confusing because there was absolutely nothing wrong with the permissions of the sqlite file.
I'm trying to retrieve data from both MySQL and SQL Server on the same console application. I manage to retrieve data from MySQL, however when I trying to retrieve data from SQL Server, I got System.ArgumentException: 'Option not supported. Parameter name: multipleactiveresultsets' error.
The following is 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>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name="MySQLDb" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;port=3306;database=sakila;uid=some_user;password=some_password"/>
<add name="SQLDb" providerName="System.Data.SqlClient" connectionString="data source=USER-PC\SQLEXPRESS;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"/>
</connectionStrings>
<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"/>
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6"/>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
</providers>
</entityFramework>
</configuration>
And my C#:
#region MySQL.
{
var dbContext = new MySQLDb();
var dbSet = dbContext.Set<Actor>();
var actors = dbSet.ToList();
}
#endregion
#region SQLServer.
{
var dbContext = new SQLDb();
var dbSet = dbContext.Set<User>();
var users = dbSet.ToList(); // <-- Throw exception.
}
#endregion
If I disable entityFramework section in app.config and MySQL code block in my C# code, I can retrieve data from SQL Server without any issue.
Version info
MySQL.Data.Entity 6.10.8
NET Framework 4.6.1
Any idea?
Update 1
Found out that the connection type for MySQLDb is MySql.Data.MySqlClient.MySqlConnection, so that works just fine. But when instantiating SQLDb, the connection type is still MySql.Data.MySqlClient.MySqlConnection instead of System.Data.SqlClient.SqlConnection. How should we fix this?
The issue is that we are using MySql.Data.Entity.MySqlEFConfiguration (in the app.config) which set the default connection factory to use MySqlConnectionFactory.
The solution is to use a custom DbConfiguration in place of MySql.Data.Entity.MySqlEFConfiguration to deter from setting the default connection factory.
public class MySQLDbConfiguration : DbConfiguration
{
public MySQLDbConfiguration()
{
SetProviderServices(MySqlProviderInvariantName.ProviderName, new MySqlProviderServices());
SetProviderFactory(MySqlProviderInvariantName.ProviderName, new MySqlClientFactory());
}
}
Declare the instance as readonly somewhere in the code,
private static readonly MySQLDbConfiguration DBConfig = new MySQLDbConfiguration();
and set the configuration PRIOR TO using any EF features
DbConfiguration.SetConfiguration(DBConfig);
And our app.config now becomes
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name="MySQLDb" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;port=3306;database=sakila;uid=some_user;password=some_password"/>
<add name="SQLDb" providerName="System.Data.SqlClient" connectionString="data source=USER-PC\SQLEXPRESS;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"/>
</connectionStrings>
</configuration>
If you're opt to use app.config instead of deriving a custom DbConfiguration, you can do the following
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- Alternative to custom DbConfiguration. -->
<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>
<providers>
<provider invariantName = "MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6"/>
</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.10.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
</DbProviderFactories>
</system.data>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name="MySQLDb" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;port=3306;database=sakila;uid=some_user;password=some_password"/>
<add name="SQLDb" providerName="System.Data.SqlClient" connectionString="data source=USER-PC\SQLEXPRESS;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"/>
</connectionStrings>
</configuration>
If you are using asp net 5.0, install the Nuget found here, but first uninstall Mysql.data.
In Visual Studio 2017 version 15.7.4 i have asp.net project with PostgresQL database. When i making ADO.NET Entity Data Model with PostgresQL it makes .edmx[Diagram] object correctly, but showng nothing in MyModel.Designer.cs:
// T4 code generation is enabled for model 'C:\Users\User\Desktop\Alibek1\Alibek1\Model1.edmx'.
// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
// is open in the designer.
// If no context and entity classes have been generated, it may be because you created an empty model but
// have not yet chosen which version of Entity Framework to use. To generate a context class and entity
// classes for your model, open the model in the designer, right-click on the designer surface, and
// select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
// Item...'.
When i'm clicking Generate Database from Model in my Model1.edmx it shows error:
enter image description here
That says: The ADO.NET provider with invariant name 'Npgsql' is either not registered in the machine or application config file, or could not be loaded.
Here's some parts of my Web.config:
` <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 -->
</configSections>
<connectionStrings>
<add name="DefaultConnection" connectionString="Server=localhost;user id=postgres;password=123;database=postgres;" providerName="Npgsql" /><add name="Model1" connectionString="Host=localhost;Database=postgres;Username=postgres;Persist Security Info=True;Password=123" providerName="Npgsql" /><add name="postgresEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=Npgsql;provider connection string="Host=localhost;Database=postgres;Username=postgres;Password=123"" providerName="System.Data.EntityClient" /><add name="postgresEntities1" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=Npgsql;provider connection string="Host=localhost;Database=postgres;Username=postgres;Password=123;Persist Security Info=True"" providerName="System.Data.EntityClient" /><add name="postgresEntities2" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=Npgsql;provider connection string="Host=localhost;Database=postgres;Username=postgres;Persist Security Info=True"" providerName="System.Data.EntityClient" /><add name="postgresEntities3" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=Npgsql;provider connection string="Host=localhost;Database=postgres;Username=postgres;Password=123;Persist Security Info=True"" providerName="System.Data.EntityClient" /></connectionStrings>
<system.data>
<DbProviderFactories>
<add name="Npgsql Data Provider" invariant="Npgsql" description=".Net Data Provider for PostgreSQL" type="Npgsql.NpgsqlFactory, Npgsql, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7"/>
<add name="dotConnect for PostgreSQL" invariant="Devart.Data.PostgreSql" description="Devart dotConnect for PostgreSQL" type="Devart.Data.PostgreSql.PgSqlProviderFactory, Devart.Data.PostgreSql, Version= 7.11.1190.0, Culture=neutral, PublicKeyToken=09af7300eec23701" />
</DbProviderFactories>`
` <system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1" />
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
</httpModules>`
` <providers>
<provider invariantName="Devart.Data.PostgreSql" type="Devart.Data.PostgreSql.Entity.PgSqlEntityProviderServices, Devart.Data.PostgreSql.Entity.EF6, Version=7.11.1190.0, Culture=neutral, PublicKeyToken=09af7300eec23701" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, EntityFramework6.Npgsql" />
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.10.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d">
</provider></providers> `
I'm trying to setup IdentityServer3 to work with Oracle database. I've got working MSSQL solution and I need Oracle variation too.
During initialization I get following error. It looks like provider reaches timeout (30-45 s) and then throws the exception.
The supplied SqlConnection does not specify an initial catalog or AttachDBFileName.
Error occurs in System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create. To be more specific in
IdentityServer3.EntityFramework.DbModelBuilderExtensions
.RegisterScopeChildTablesForDelete[TScope](DbContext ctx) in
IdentityServer3.EntityFramework\Source\Core.EntityFramework\Extensions
\DbModelBuilderExtensions.cs
Here is my web.config connection string:
<add name="ApplicationDbContext"
providerName="Oracle.ManagedDataAccess.Client"
connectionString="User Id=xxxxxxx;
Password=xxxxxxx;
Data Source=OracleDataSource" />
and here is the rest of web.config (any how related to Oracle)
<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="Oracle.ManagedDataAccess.Client" type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="Oracle.ManagedDataAccess.Client" />
<add name="ODP.NET, Managed Driver" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
<oracle.manageddataaccess.client>
<version number="*">
<dataSources>
<dataSource alias="OracleDataSource" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE))) " />
</dataSources>
</version>
</oracle.manageddataaccess.client>
How can I add Initial Catalog to my connection string for Oracle?
Versions
IdentityServer3: v 2.5
EntityFramework: 6.1.3
Oracle ManagedDataAccess EntityFramework: 12.1.4
Update 1:
I've tried simply adding Initial Catalog to my conn string, but it doesn't seem to work (Oracle XE, C++ ADO):
<add name="ApplicationDbContext"
providerName="Oracle.ManagedDataAccess.Client"
connectionString="User Id=xxxxxxx;
Password=xxxxxxx;
Data Source=OracleDataSource;
Initial catalog=XE" />
Maybe XE is not the name of my database? Should I use schema instead?
The problem was defaultConnectionFactory
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
After replacing with OracleConnectionFactory things moved on
<defaultConnectionFactory type="Oracle.ManagedDataAccess.EntityFramework.OracleConnectionFactory, Oracle.ManagedDataAccess.EntityFramework" />
In my project I am trying to use Entity Framework along with PostgreSql. But I am not able to connect to my database. I am not getting any error, it just gets stuck. I think something is wrong with my app.config, but I am not able to find out what.
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>
<entityFramework>
<defaultConnectionFactory type="Npgsql.NpgsqlFactory, Npgsql" />
<providers>
<provider invariantName="Npgsql"
type="Npgsql.NpgsqlServices, Npgsql.EntityFramework" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<add name="Npgsql Data Provider" invariant="Npgsql"
description="Data Provider for PostgreSQL"
type="Npgsql.NpgsqlFactory, Npgsql" />
</DbProviderFactories>
</system.data>
<connectionStrings>
<add name="Entities"
connectionString="server=localhost;user id=postgres;password=4321;database=postgis"
providerName="Npgsql" />
</connectionStrings>
</configuration>
DbContext:
public class Entities : DbContext
{
public Entities() : base("Entities")
{
}
//rest of the code
}
mycode.cs
using (var db = new Entities()) // when debug it stuck here and keep running
{
// some test code
}
EDIT:
I get the following error :
"The Entity Framework provider type 'Npgsql.NpgsqlServices, Npgsql.EntityFramework' registered in the application config file for the ADO.NET provider with invariant name 'Npgsql' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application.
The problem points to a wrong provider type or assembly name.
<entityFramework>
<defaultConnectionFactory type="Npgsql.NpgsqlFactory, Npgsql" />
<providers>
<provider invariantName="Npgsql"
type="Npgsql.NpgsqlServices, Npgsql.EntityFramework" />
</providers>
</entityFramework>
The assembly name is wrong. The assembly installed by the EntityFramework6.Npgsql package is EntityFramework6.Npgsql.dll. In fact, adding the package to a new project sets the correct provider line:
<providers>
<provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, EntityFramework6.Npgsql" />
</providers>