Using Entity Framework with Oracle

I've long thought that the Entity Framework hasn't gotten a fair shake. Sure, there's some room for improvement but for an out-of-the-box ORM that ships with the framework it's not too bad.

Oracle LogoOne thing has always troubled me, though. I was never sure what kind of traction it had with data sources other than SQL Server. Recently in a project circumstances conspired in such a fashion that it would be pretty darn handy to use EF to access data in Oracle. Turns out it that despite being a little rough around the edges it's very feasible.

The Provider

The first step is to download and install an Entity Framework provider for Oracle. There are several options out there but the Oracle Data Provider for Entity Framework on CodePlex seems to be the most complete that was free.

The Database

To demonstrate I'll set up a simple oracle express database to store hockey player data.

create table  "TEAMS" 
   (	"ID" number, 
	"NAME" varchar2(256), 
	"CITY" varchar2(256), 
	 constraint "TEAMS_PK" primary key ("ID") enable
   )
/

create trigger  "BI_TEAMS" 
  before insert on "TEAMS"               
  for each row  
begin   
    select "TEAMS_SEQ".nextval into :NEW.ID from dual; 
end; 

/
alter trigger  "BI_TEAMS" enable
/

create table  "PLAYERS" 
   (	"ID" number, 
	"FULLNAME" varchar2(256), 
	"JERSEYNUMBER" number, 
	"TEAM_ID" number, 
	 constraint "PLAYERS_PK" primary key ("ID") enable, 
	 constraint "PLAYERS_FK" foreign key ("TEAM_ID")
	  references  "TEAMS" ("ID") enable
   )
/

create trigger  "BI_PLAYERS" 
  before insert on "PLAYERS"               
  for each row  
begin   
    select "PLAYERS_SEQ".nextval into :NEW.ID from dual; 
end; 

/
alter trigger  "BI_PLAYERS" enable
/

The Plumbing

With the schema and prerequisite out of the way I can get right into adding an entity model to the project in the standard way. Add entity model to project dialog

I'll generate the model from an existing database. Choose model contents dialog

Now to set up the data source. Because of the Oracle Provider that I installed above there's a new "Oracle Database" option in the Data Source list. Data source setup dialog

Now I'll set up the connection information. Connection properties dialog

Next I'll select the tables I created above to create the model from. Choose database objects dialog

Ok, now I have a basic model, but I might as well clean up the naming by using pascal-case and reasonable pluralization. Entity model designer

If this were SQL Server I'd be done. Unfortunately there's a hidden problem. The ID fields that are generated from sequences won't be handled correctly. After saving the entities the ID's will be returned as 0. I'll fix this by manually hacking the SSDL (open your .edmx file in a text editor) with StoreGeneratedPattern="Identity" attributes on the ID fields (lines 6 and 16). Note that designer may rip that change out upon future modification.

While I suppose it's not absolutely necessary it might also be prudent to modify some type metadata such as changing "number"s to "int"s in your SSDL and "Decimal"s to "Int32"s in your CSDL where applicable. Frequently these don't auto-generate with the desired values especially with XE.

<EntityType Name="PLAYERS">
  <Key>
    <PropertyRef Name="ID" />
  </Key>
  <Property Name="ID" Type="int" Nullable="false" 
        StoreGeneratedPattern="Identity"/>
  <Property Name="FULLNAME" Type="varchar2" MaxLength="256" />
  <Property Name="JERSEYNUMBER" Type="int" />
  <Property Name="TEAM_ID" Type="int" />
</EntityType>
<EntityType Name="TEAMS">
  <Key>
    <PropertyRef Name="ID" />
  </Key>
  <Property Name="ID" Type="int" Nullable="false" 
        StoreGeneratedPattern="Identity"/>
  <Property Name="NAME" Type="varchar2" MaxLength="256" />
  <Property Name="CITY" Type="varchar2" MaxLength="256" />
</EntityType>

The Code

The plumbing work is over! Now I'll use the following C# to populate some data into my Oracle database.

using (HockeyEntities entites = new HockeyEntities())
{
    Team team = new Team();
    team.Name = "Penguins";
    team.City = "Pittsburgh";
    entites.AddToTeams(team);

    Player player = new Player();
    player.FullName = "Evgeni Malkin";
    player.JerseyNumber = 71;
    player.Team = team;

    player = new Player();
    player.FullName = "Sidney Crosby";
    player.JerseyNumber = 87;
    player.Team = team;

    team = new Team();
    team.Name = "Capitals";
    team.City = "Washington";
    entites.AddToTeams(team);

    player = new Player();
    player.FullName = "Alexander Ovechkin";
    player.JerseyNumber = 8;
    player.Team = team;

    entites.SaveChanges();
}

And I can query the data created above with:

using (HockeyEntities entites = new HockeyEntities())
{
    var players = from p in entites.Players
            where p.Team.City == "Pittsburgh"
            select p;

    foreach (Player p in players)
    {
        Console.WriteLine(p.FullName);
    }
}

Resulting in:

Evgeni Malkin
Sidney Crosby

Conclusion

Other that some minor tweaking to SSDL using EF to access Oracle isn't too bad. I assume that as time goes on issues like that will get worked out and the experience will be improve.

Created on 2009-12-22 21:30:00
Share on Facebook Facebook
Comment Feed
Add a Comment: (HTML not accepted. URLs will automatically be converted to links)
Body
Nickname (Login || Register)
Home Page
Email Addy(kept private)
Are you human?
Tags:
linq .Net performance sql 2008 sql server powershell indexes scripting reporting services filestream ruby ironruby entity framework EF testing .net framework 4.0 ADO.NET SSRS rs setpolicies vb cte c# podcasts webdav exchange server data warehousing Data Services Web Services Astoria jQuery database object oriented cql refactoring remoting simpledb cloud HTML GObject GNOME Vala BI couchdb django ORM python erlang functional C curl stackless concurrency Groovy Java JVM dynamic tools windows ironpython dlr systems programming go CAPTCHA appengine natural language full-text rails lucene wave clr parallel virtualization Oracle iPhone xml Objective-C Haiku security cocoa touch C++ BeOS Operating Systems Lucene monitoring Solr lisp VS 2010
Blog History:
Solrnet, a Solr Client Library for .Net - 03/08/2010
Monitoring Solr with LucidGaze - 02/21/2010
Haiku, an Open Source Continuation of BeOS - 02/10/2010
Basic Authentication with a NSURLRequest in Cocoa Touch - 01/24/2010
Asynchronous Programming in Cocoa Touch - 01/17/2010
NSXML-like XPath Support in Cocoa Touch with TouchXML - 01/03/2010
Using Solr in Django for Full-Text Searching via Solango - 01/01/2010
Using Entity Framework with Oracle - 12/22/2009
Solutions to Common VirtualBox Problems - 12/20/2009
Parallel Programming with the Task Parallel Library and PLINQ in .Net 4.0 - 12/14/2009
Clojure, A Lisp for the JVM and CLR - 12/13/2009
Google Wave Robots in Java - 12/07/2009
Employing Solr/Lucene with SQL Server for Full-Text Searching - 12/05/2009
Full-Text Indexing in Ruby Using Ferret - 11/28/2009
Home-Brewing a Full-Text Search in Google's AppEngine - 11/22/2009
Using reCAPTCHA With Django - 11/21/2009
Phat Go Code Launched - 11/19/2009
A Little More of Google's Go - 11/17/2009
First Impressions of Go, Google's New Systems Language - 11/14/2009
Scripting Your .Net Applications with IronPython - 11/03/2009
Windows Services in Python - 11/02/2009
My Tool List - 10/26/2009
Groovy: Dynamic Language for the JVM... Groovy! - 10/23/2009
Easy Concurrency with Stackless Python - 10/03/2009
C from erlang via linked-in driver - 09/16/2009
Templating with NDjango - 09/06/2009
A little bit o' Erlang - 08/23/2009
Tale of a Website, from Rails to ASP.NET to Django - 08/20/2009
Now in Django - 08/19/2009
Stored Procedures in Django - 08/09/2009
CouchDBExtension - 08/06/2009
POCO Entities in ADO.NET 4.0 - 07/30/2009
Accessing SimpleDB from SSRS - 07/22/2009
Easy GNOME Development with the Vala Programming Language - 07/16/2009
HTML Parsing with Ruby and Nokogiri - 07/12/2009
Amazon SimpleDB Batched PUTs Usage and Performance - 07/10/2009
PowerShell 2.0 Out-GridView, ISE and ScriptCmdlets - 07/05/2009
Asynchronous and remote execution with powershell 2 ctp3 - 06/30/2009
Understanding Source Code with NDepend and CQL - 06/22/2009
Object Oriented Databases with db4o - 06/07/2009
ADO.Net Data Services with jQuery - 05/29/2009
Exchange webdav automation - 05/26/2009
Podcasts - 05/26/2009
Linq to Object Performance - 05/11/2009
SQL 2008 and powershell - 01/25/2009
SQL 2008 filtered indexes - 06/11/2008
SQL 2008's table valued parameters - 05/11/2008
SQL 2008's MERGE statement - 04/22/2008
ironruby - 04/11/2008
SSRS scripting with RS.EXE - 11/20/2007
SQL 2008 FILESTREAM - 08/04/2007
CTE Concatenation - 01/01/2007