It’s an easy way to get Oracle Managed Driver
and Entity Framework Code First
to work properly in Visual Studio 2013.
We will use nuget packages which is easy and fast but lack some features and to make work correctly I follow the bellow steps:
1- Create New Windows Forms Application and target .Net Framework 4.6.1
2- install EntityFramework by executing
PM> Install-Package EntityFramework -Version 6.2.0
and we must execut this first because it update the App.Config file correctly so the file will be somthing like:
<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>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
3- Install Oracle.ManagedDataAccess.EntityFramework which will install it’s dependency Oracle.ManagedDataAccess also by excute
PM> Install-Package Oracle.ManagedDataAccess.EntityFramework -Version 12.2.1100
now the App.config file should look like :
<?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"/>
<section name="oracle.manageddataaccess.client" type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
<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.122.1.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.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342"/>
</DbProviderFactories>
</system.data>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<publisherPolicy apply="no"/>
<assemblyIdentity name="Oracle.ManagedDataAccess" publicKeyToken="89b483f429c47342" culture="neutral"/>
<bindingRedirect oldVersion="4.121.0.0 - 4.65535.65535.65535" newVersion="4.122.1.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
<oracle.manageddataaccess.client>
<version number="*">
<dataSources>
<dataSource alias="SampleDataSource" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL))) "/>
</dataSources>
</version>
</oracle.manageddataaccess.client>
<connectionStrings>
<add name="OracleDbContext" providerName="Oracle.ManagedDataAccess.Client" connectionString="User Id=oracle_user;Password=oracle_user_password;Data Source=oracle"/>
</connectionStrings>
</configuration>
4- update the connectionStrings
section with the correct db data and make use of dataSources
in oracle.manageddataaccess.client
section if you want.
5- create your DbContext class and your tables classes like the bellow :
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace WindowsFormsApplication2
{
public class myDbContext : DbContext
{
public myDbContext()
: base("name=OracleDbContext") // connectionString name in App.config
{
Database.SetInitializer<myDbContext>(null); // I already have the database , don't create or modify it :)
}
public virtual DbSet<myDbTableName> myDbTableNameSet { get; set; }
}
[Table("mySchema.myDbTableName")]
public partial class myDbTableName
{
public myDbTableName()
{
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long ID { get; set; }
[Required]
[StringLength(32)]
public string FirstName { get; set; }
[Required]
[StringLength(32)]
public string LastName { get; set; }
[StringLength(200)]
public string Address { get; set; }
public long? SampleData { get; set; }
}
}
No we can start working just like this :
using(var myDB = new myDbContext())
{
this.Text = myDB.myDbTableNameSet.Count().ToString();
}
Now to the interested part ;)
what we miss here is the auto generating of DbConext
and Tables Classes
from database which we can be done through visual studio by adding new Entity Data Model
Then Choose Code First from database
option
Then choose your database connection or create a new one :
Now if you hit Next
you may find the Enity Data Model Wizard
window Just Disappeared !! without any messages and you don’t know the issue !! don’t worry I’ll tell you :)
The issue is that we are using a version of Entity Framework
and Oreacle Managed Driver
which are newer that the ones intended to be used by the Enity Data Model Wizard
because this wizard is trying to use the version installed with Oracle Developer Tools (ODT) for VS2013
.
An easy fix for this issue is using the same Oracle Managed Driver
version which came with ODT
while generating the classes and revert back to our latest version or better create a separate project for classes generation with this configuration.
To do this just remove the [ Oracle.ManagedDataAccess , Oracle.ManagedDataAccess.EntityFramework
] DLLs from the project References
and add them from [ C:\Program Files (x86)\Oracle Developer Tools for VS2013\odp.net\managed\common
]
If you rebuild your application and try the Enity Data Model Wizard
again you may face and error message like this :
Your project references the latest version of Entity Framework; however, an Entity Framework database provider compatible with this version could not be found for your data connection. If you have already installed a compatible provider, ensure you have rebuild your project before performing this action. Otherwise, exist this wizard, install a compatible provider and rebuild your project before performing this action.
This is because our App.Config
file contains binding information related to the nuget Oracle Managed Driver DLLs
version and there is a simple solution to this error :) we have just to remove this version specific data from App.config
file and rebuild the application.
The App.config
should look like :
<?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"/>
<section name="oracle.manageddataaccess.client" type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
<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"/>
</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"/>
</DbProviderFactories>
</system.data>
<oracle.manageddataaccess.client>
<version number="*">
<dataSources>
<dataSource alias="SampleDataSource" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL))) "/>
</dataSources>
</version>
</oracle.manageddataaccess.client>
<connectionStrings>
<add name="OracleDbContext" providerName="Oracle.ManagedDataAccess.Client" connectionString="User Id=oracle_user;Password=oracle_user_password;Data Source=oracle"/>
</connectionStrings>
</configuration>
Notice that I also removed <runtime>
section and congratulations now you can see Choose Your Database Objects and Settings
page , have fun and happy coding :)