ENTITY FRAMEWORK
At a Glance
- Enterprise quality ORM framework for .NET
-
(Mostly) open source via Apache 2.0 license
- Originally released in 2008, current version: 6
- Database agnostic
-
Largely convention based
- Distributed through NuGet
Key Features
-
LINQ to Entities (think: strongly typed SQL without the pain)
-
Enterprise features: transactions, concurrency, logging, wide database support
- Async support
- Supports N-Tier architecture (self-tracking, DTO model)
- Migrations
- Code First workflow
Context
Workflows
Model First
(Big) Model First
Code First
//Automatically maps to dbo.Orders table
public class Order {
public int Id {get;set;}
public string Name {get;set;}
public virtual Customer Customer {get;set;}
public virtual List<Product> Products {get;set;}
}
Query Interface
using (EFContext context = new EFContext())
{
var orders = context.Orders.Where(o=> o.UserId == userId);
}
List<Order> orders = new List<Order>();
using (SqlConnection connection = new SqlConnection("Server: 192.168...")) { conn.Open(); using (SqlCommand command = connection.CreateCommand()){ command.CommandText = "sp_GetOrders"; command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@UserID", userID); using(SqlDataReader = reader = command.ExecuteReader()){ while(reader.Read()){ Order newOrder = new Order(); newOrder.ID = Convert.ToInt32(reader["Id"]); newOrder.Name = reader["Name"].ToString(); orders.Add(newOrder); } } } }
Migrations
- Similar to Active Record
- Not enabled by default
- Supports "code first" migrations
- Does not export schema
- Supports seed data
- Supports scripting migration
- Doesn't play nicely with stored procedures
Enable-Migrations -EnableAutomaticMigrations
Add-Migration InitialCreate
Add-Migration AddOrderNotesColumn
Update Database
Relationship
Loading Strategies
-
Eager - think inner/left join
- Lazy - dynamically executed when accessed
- Explicit - null until explicitly loaded
vs Active Record
- Model is defined as POCOs vs dynamic at runtime
- "code first" migrations
- Active Record objects are CUD aware (i.e. person.save) whereas in EF you have DbContext
- Active Record classes inherit from ActiveRecord::Base whereas EF classes do not (need) to inherit from base class
Criticisms
- Testability (mocking DbContext not easy)
- Performance
- Separation of concerns (biz logic?)
- Produced SQL complex / inefficient sometimes
- Bloatware (1,000,000+ lines of code)
v6
- Performance improvements
- Stored procedures for CUD
- Code based configuration enhancements
- Enum support
- Async queries built-in
- Testability improvements
- Query interception (logging, custom hooks ,etc.)
- Connection resilience
v7
- Estimated release: Fall 2014
- Completely new codebase
- Fully open source
- Wider platform support including Azure and Mono/Xamarin (Linux/Mac)
- Code First Workflow primarily supported
- Will not contain ObjectContext, Entity SQL, EntityConnection, EntityCommand, etc.
DEMO
(finally)