Multiple EF6 DbContext for one DbConfiguration in ASP.NET 5 - entity-framework-6

I'm trying to port my MVC 5 application to MVC 6. I'm using Devart dotConnect for MySql and Oracle. I have trouble configuring my application.
Right now I have the following entries:
<entityFramework>
<providers>
<provider invariantName="Devart.Data.MySql" type="Devart.Data.MySql.Entity.MySqlEntityProviderServices, Devart.Data.MySql.Entity" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="Devart.Data.MySql" />
<add name="dotConnect for MySQL" invariant="Devart.Data.MySql" description="Devart dotConnect for MySQL" type="Devart.Data.MySql.MySqlProviderFactory, Devart.Data.MySql" />
</DbProviderFactories>
</system.data>
My application have 3 DbContext classes (2x MySql, 1x Oracle) in separate assemblies, and I can only have 1 DbConfiguration class (Entity Framework 6 limitation).
If I set this configuration other contexts complain that they cannot see assembly with DbConfiguration class.
How do I get over that limitation?

I found myself in a similar situation the other day, and had to rely on web.config to enrich the configuration
<entityFramework codeConfigurationType="MyNamespace.MyDbConfiguration, MyAssembly">
...Your EF config...
</entityFramework>
Edit
The second option is to place DbConfigurationTypeAttribute on your context class
[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}
For more details check these resources
Ef6 docs: Code-Based Configuration Type (EF6 Onwards)
Ef6 docs: Moving DbConfiguration

Related

Using Effort with EF6 in a DB First approach

I'm using the Model First approach with EF6 and I'm trying to use Entity Framework Effort to develop in-memory tests.
Here is what I do in my test:
var inMemoryConnection = Effort.DbConnectionFactory.CreateTransient("name=MyEntities");
var inMemoryContext = new MyEntities(inMemoryConnection);
MyEntities:
public partial class MyEntities: DbContext
{
public MyEntities(DbConnection dbConnection)
: base(dbConnection, contextOwnsConnection: true)
{
}
When I run the tests, I get an error saying I didn't specify any [key] attributes which is normal since I am not using a Code First approach. Therefor, the OnModelCreating method is called and shouldn't have to.
Is there a way to use Effort in a Model First design without having to add these attributes?
Thanks !
I found my mistake.
Turns out Effort.DbConnectionFactory.CreateTransient is used for Code-First.
Instead if you're working with a .edmx, Model-First, it is Effort.EntityConnectionFactory.CreateTransient("name=MyEntities") you have to use.
I too had a bit of a difficult time in trying to get Effort to work with a DB first, or model first as it's also known, approach. This is what I did to make it work:
Download the Effort.EF6 nuget package
Add the effort.provider to the entity-framework config section:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="Effort.Provider" type="Effort.Provider.EffortProviderServices,Effort" />
</providers>
</entityFramework>
Replace the sql-provider with the Effort-provider in the connection-string:
<connectionStrings>
<add name="testDb" providerName="Effort.Provider" connectionString="metadata=res://*/StaginDB.csdl|res://*/StaginDB.ssdl|res://*/StaginDB.msl;provider=System.Data.SqlClient;provider connection string="data source=testDB;initial catalog=foobaroo;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" />
</connectionStrings>
If your model-first context doesn't offer a constructor you can inject a connection into, you can modify your tt-template to do so:
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
// I added this constructor so I could inject a db-connection into the context:
public <#=code.Escape(container)#>(System.Data.Common.DbConnection dbConnection, bool contextOwnsConnection)
: base(dbConnection, contextOwnsConnection)
{
}
// Original constructor
public <#=code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
this.Configuration.LazyLoa.... etc. etc.
And we can now use that constructor to instantiate a connection, and an Effort-based in-memory db-context based on this connection:
System.Data.Common.DbConnection connection = Effort.EntityConnectionFactory.CreateTransient("name=KPDBSTAGINGEntities");
TestDbContext testDbContext = new testDbContext(connection, false);
TestDbContext.your-entity.add( new your-entity() { etc. tec. });
TestDbContext.SaveChanges();
Hope this helps.
P.S. Others have had to add a db-provider-factory section to their config. This was not required for me, but maybe for you:
<system.data>
<DbProviderFactories>
<add name="Effort.Provider" invariant="Effort.Provider" description="Effort.Provider" type="Effort.Provider.EffortProviderFactory,Effort" />
</DbProviderFactories>
</system.data>

Create user database via code first ASP.NET MVC

I'm trying to use a MySQL database with asp.net MVC via a code first approach and I don't know how to create the tables, I thought it would create by itself.
I get the message : "Table 'XXX.aspnetusers' doesn't exist"
Do I need to run migrations or something like that?
Thanks
I got a little further by using update-database. You must have change your connection string and your provider to correspond to your MySql
Example :
<add name="DefaultConnection" connectionString="server=127.0.0.1;User Id=root;password=;database=myDB" providerName="MySql.Data.MySqlClient" />
Provider :
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"></provider>
</providers>
</entityFramework>
You should also put this on your dbContext :
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
Thanks

The Entity Framework provider type 'Oracle.ManagedDataAccess.EntityFramework' could not be loaded

I am trying to connect to Oracle using the Oracle Data Provider.NET (ODP.NET) using Entity Framework v6 in an MVC application.
I have installed ODP.NET from here:
https://www.nuget.org/packages/odp.net.entityframework/6.121.1-beta
I have configured my web.config file as follows:
<connectionStrings>
<add name="MyDB" connectionString="User ID=MyUser;Password=MyPassword;Data Source=MyDatabase; Persist Security Info=False" providerName="Oracle.ManagedDataAccess" />
</connectionStrings>
<entityFramework>
<providers>
<provider invariantName="Oracle.ManagedDataAccess.Client" type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</providers>
</entityFramework>
However, when I try to call my EF Context, I get the following error:
The Entity Framework provider type 'Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342' registered in the application config file for the ADO.NET provider with invariant name 'Oracle.ManagedDataAccess.EntityFramework' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application
I have spent a lot of time searching for help with this. Would be very grateful for any help!
Thanks!
Martin
Adding this section to the web.config, along with the steps above, seems to have fixed this:
<system.data>
<DbProviderFactories>
<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.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
There can be your framework problem. Please check your framework by right clicking on project--> properties check it is 4.5 version.
And then right click on Refrences--> Manage NuGet Package.. go to the nuget.org and type "Official Oracle ODP.NET" in search box. and install Official Oracle ODP.NET, Managed Entity Framework.
Official Oracle ODP.NET, Managed Driver.
Oracle Data Provider for .Net x84/x64.
Thanking you

Entity Framework providers must declare a static property or field named 'Instance' that returns the singleton instance

I am using Entity Framework 6 in a ASP.NET MVC application. I am using a Code First approach to try and connect to an existing database.
Firstly, I have set up a Model as follows:
public class Employee
{
public int ID { get; set; }
public string PAYCODE { get; set; }
}
Secondly, I have a Context as follows:
public class EmployeeContext : DbContext
{
public EmployeeContext()
: base("EmployeeDB")
{
}
public DbSet<Employee> Employees { get; set; }
}
Thirdly, I have specified the connection to the DB in the web.config:
<connectionStrings>
<add name="EmployeeDB" connectionString="Server=MyServer;Database=MyDB;User ID=MyUserID;Password=MyPassword;Trusted_Connection=False" providerName="System.Data.SqlClient" />
</connectionStrings>
Finally, I call my context from a Controller class as follows:
var db = new EmployeeContext();
However, this throws the following run-time error:
The Entity Framework provider type 'System.Data.Common.DbProviderConfigurationHandler, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' did not have a static property or field named 'Instance'. Entity Framework providers must declare a static property or field named 'Instance' that returns the singleton instance of the provider.
I would be extremely grateful if anyone can shed some light on this error - I have tried searching on the Web, and have followed Microsoft examples.
Many thanks!
Martin
Added in response to question below:
The following is at the foot of my web.config:
<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" />
<provider invariantName="System.Data.OracleClient" type="System.Data.Common.DbProviderConfigurationHandler, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</providers>
I have found out that the error message was caused by trying to use 'System.Data.OracleClient' as a provider for EF6.
It looks to me that this provider cannot be used to connect to Oracle from an EF6 application.
After some searching, I am trying to replace the provider with Devart dotConnect, but the version that my company owns seems to be too out of date to support EF6.
There doesn't seem to be many resources to help with connecting EF6 to Oracle.
Looks like you need to change your connection factory to SqlConnectionFactory. http://blogs.msdn.com/b/davidobando/archive/2012/08/14/changing-ef-s-default-provider-from-localdb-to-sql-server.aspx

why connection string is not found from my class library to another class library?

I am having the architecture like this :
Where MVC layer is the presentation layer. EF is class library and Repository is another class library.I am trying to insert data to database from repository by creating the EF context object. Added EF reference into Repository class library. EF having the edmx file. its app.config having the connection string generated by EF.
code is :
public bool CreateUser(User _user)
{
context.Users.Add(_user);
context.SaveChanges();
return true;
}
but while executing this I am getting following exception :
No connection string named 'MyEntitiesConnection' could be found in the application config file.
I tried to add same connection string with same name in repository app.config. but not working. anyone have solution ?
Edited:
connection string is :
<add name="MyEntitiesConnection" connectionString="metadata=res://*/EF.Entities.csdl|res://*/EF.Entities.ssdl|res://*/EF.Entities.msl;provider=System.Data.SqlClient;provider connection string="data source=Servername\MSSQL2008R2;initial catalog=MyDBName;persist security info=True;user id=sa;MultipleActiveResultSets=True;App=EntityFramework;" providerName="System.Data.EntityClient" />
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=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="MyEntitiesConnection" connectionString="metadata=res://*/EF.Entities.csdl|res://*/EF.Entities.ssdl|res://*/EF.Entities.msl;provider=System.Data.SqlClient;provider connection string="data source=Servername\MSSQL2008R2;initial catalog=MyDBName;persist security info=True;user id=sa;MultipleActiveResultSets=True;App=EntityFramework;" providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
</configuration>
In any .NET application, only one config file is the natural starting point for looking for configuration information. For web applications, that's the web.config file at the root of the application1.
Whilst you may have a file called app.config in your repository project (and, indeed, some VS tooling may have added one) or your EF project, it's not used when you try to read configuration information.
The connection string section needs to exist in the web.config of your MVC app.
1For non-web applications, it's the app.config for the project that produces the .exe file and that gets automatically copied as XXX.exe.config during the build.

Resources