Tuesday, 1 January 2019

Entity Framework Core

Entity Framework Core is the new version of Entity Framework after EF 6.x. It is open-source, lightweight, extensible and a cross-platform version of Entity Framework data access technology.


Entity Framework is an Object/Relational Mapping (O/RM) framework. It is an enhancement to ADO.NET that gives developers an automated mechanism for accessing & storing the data in the database.
EF Core is intended to be used with .NET Core applications. However, it can also be used with standard .NET 4.5+ framework based applications.
The following figure illustrates the supported application types, .NET Frameworks and OSs.

EF Core Version History

EF Core VersionRelease Date
EF Core 2.0August 2017
EF Core 1.1November 2016
EF Core 1.0June 2016
EF Core Official Documentation: https://docs.microsoft.com/ef/core

EF Core Development Approaches

EF Core supports two development approaches 1) Code-First 2) Database-First. EF Core mainly targets the code-first approach and provides little support for the database-first approach because the visual designer or wizard for DB model is not supported as of EF Core 2.0.
In the code-first approach, EF Core API creates the database and tables using migration based on the conventions and configuration provided in your domain classes. This approach is useful in Domain Driven Design (DDD).
In the database-first approach, EF Core API creates the domain and context classes based on your existing database using EF Core commands. This has limited support in EF Core as it does not support visual designer or wizard.

EF Core vs EF 6

Entity Framework Core is the new and improved version of Entity Framework for .NET Core applications. EF Core is new, so still not as mature as EF 6.
EF Core continues to support the following features and concepts, same as EF 6.
  1. DbContext & DbSet
  2. Data Model
  3. Querying using Linq-to-Entities
  4. Change Tracking
  5. SaveChanges
  6. Migrations
EF Core will include most of the features of EF 6 gradually. However, there are some features of EF 6 which are not supported in EF Core 2.0 such as:
  1. EDMX/ Graphical Visualization of Model
  2. Entity Data Model Wizard (for DB-First approach)
  3. ObjectContext API
  4. Querying using Entity SQL.
  5. Automated Migration
  6. Inheritance: Table per type (TPT)
  7. Inheritance: Table per concrete class (TPC)
  8. Many-to-Many without join entity
  9. Entity Splitting
  10. Spatial Data
  11. Lazy loading of related data
  12. Stored procedure mapping with DbContext for CUD operation
  13. Seed data
  14. Automatic migration
EF Core includes the following new features which are not supported in EF 6.x:
  1. Easy relationship configuration
  2. Batch INSERT, UPDATE, and DELETE operations
  3. In-memory provider for testing
  4. Support for IoC (Inversion of Control)
  5. Unique constraints
  6. Shadow properties
  7. Alternate keys
  8. Global query filter
  9. Field mapping
  10. DbContext pooling
  11. Better patterns for handling disconnected entity graphs
Learn more on EF Core and EF 6 differences at here.

EF Core Database Providers

Entity Framework Core uses a provider model to access many different databases. EF Core includes providers as NuGet packages which you need to install.
The following table lists database providers and NuGet packages for EF Core.
Learn to install EF Core in the next chapter.

Monday, 31 December 2018

Persistence in Entity Framework

There are two scenarios when persisting (saving) an entity to the database using Entity Framework: the Connected Scenario and the Disconnected Scenario.

Connected Scenario

In the connected scenario, the same instance of the context class (derived from DbContext) is used in retrieving and saving entities. It keeps track of all entities during its lifetime. This is useful in windows applications with the local database or the database on the same network.
Pros:
  • Performs fast.
  • The context keeps track of all entities and automatically sets an appropriate state as and when changes occurr to entities.
Cons:
  • The context stays alive, so the connection with the database stays open.
  • Utilizes more resources.

Disconnected Scenario

In the disconnected scenario, different instances of the context are used to retrieve and save entities to the database. An instance of the context is disposed after retrieving data and a new instance is created to save entities to the database.
The disconnected scenario is complex because an instance of the context doesn't track entities, so you must set an appropriate state to each entity before saving entities using SaveChanges(). In the figure above, the application retrieves an entity graph using Context 1 and then the application performs some CUD (Create, Update, Delete) operations using Context 2. Context 2 doesn't know what operation has been performed on the entity graph in this scenario.
This is useful in web applications or applications with a remote database.
Pros:
  • Utilizes less resources compared to the connected scenario.
  • No open connection with the database.
Cons:
  • Need to set an appropriate state to each entity before saving.
  • Performs slower than the connected scenario.

Development Approaches with Entity Framework

There are three different approaches you can use while developing your application using Entity Framework:
  1. Database-First
  2. Code-First
  3. Model-First

Database-First Approach

In the database-first development approach, you generate the context and entities for the existing database using EDM wizard integrated in Visual Studio or executing EF commands.
EF 6 supports the database-first approach extensively. Visit EF 6 DB-First section to learn about the database-first approach using EF 6.
EF Core includes limited support for this approach.

Code-First Approach

Use this approach when you do not have an existing database for your application. In the code-first approach, you start writing your entities (domain classes) and context class first and then create the database from these classes using migration commands.
Developers who follow the Domain-Driven Design (DDD) principles, prefer to begin with coding their domain classes first and then generate the database required to persist their data.
Visit the EF 6 Code-First Tutorials section to learn EF 6 code-first development from scratch.
Visit EF Core section to learn about the code-first approach in EF Core.

Model-First Approach

In the model-first approach, you create entities, relationships, and inheritance hierarchies directly on the visual designer integrated in Visual Studio and then generate entities, the context class, and the database script from your visual model.
EF 6 includes limited support for this approach.
EF Core does not support this approach.

Choosing the Development Approach for Your Application

Use the following flow chart to decide which is the right approach to develop your application using Entity Framework:
As per the above figure, if you already have an existing application with domain classes, then you can use the code-first approach because you can create a database from your existing classes. If you have an existing database, then you can create an EDM from an existing database in the database-first approach. If you do not have an existing database or domain classes, and you prefer to design your DB model on the visual designer, then go for the Model-first approach.

Entity States in Entity Framework

EF API maintains the state of each entity during an its lifetime. Each entity has a state based on the operation performed on it via the context class. The entity state represented by an enum System.Data.Entity.EntityState in EF 6 and Microsoft.EntityFrameworkCore.EntityState in EF Core with the following values:
  1. Added
  2. Modified
  3. Deleted
  4. Unchanged
  5. Detached
The Context not only holds the reference to all the entity objects as soon as retrieved from the database, but also keeps track of entity states and maintains modifications made to the properties of the entity. This feature is known as Change Tracking.
The change in entity state from the Unchanged to the Modified state is the only state that's automatically handled by the context. All other changes must be made explicitly using proper methods of DbContext or DbSet. (You will learn about these methods in EF 6 and EF Core sections.)
EF API builds and executes the INSERT, UPDATE, and DELETE commands based on the state of an entity when the context.SaveChanges() method is called. It executes the INSERT command for the entities with Added state, the UPDATE command for the entities with Modified state and the DELETE command for the entities in Deleted state. The context does not track entities in the Detached state. The following figure illustrates the significance of entity states:
Thus, entity states play an important role in Entity Framework.

Types of Entities in Entity Framework

There are two types of Entities in Entity Framework: POCO Entities and Dynamic Proxy Entities.

POCO Entities (Plain Old CLR Object)

A POCO entity is a class that doesn't depend on any framework-specific base class. It is like any other normal .NET CLR class, which is why it is called "Plain Old CLR Objects".
POCO entities are supported in both EF 6 and EF Core.
These POCO entities (also known as persistence-ignorant objects) support most of the same query, insert, update, and delete behaviors as entity types that are generated by the Entity Data Model. The following is an example of Student POCO entity.
public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public byte[]  Photo { get; set; }
    public decimal Height { get; set; }
    public float Weight { get; set; }
        
    public StudentAddress StudentAddress { get; set; }
    public Grade Grade { get; set; }
}

Dynamic Proxy Entities (POCO Proxy)

Dynamic Proxy is a runtime proxy class which wraps POCO entity. Dynamic proxy entities allow lazy loading.
Note: Dynamic proxy entities are only supported in EF 6. EF Core 2.0 does not support them yet.
A POCO entity should meet the following requirements to become a POCO proxy:
  1. A POCO class must be declared with public access.
  2. A POCO class must not be sealed (NotInheritable in Visual Basic).
  3. A POCO class must not be abstract (MustInherit in Visual Basic).
  4. Each navigation property must be declared as public, virtual.
  5. Each collection property must be ICollection<T>.
  6. The ProxyCreationEnabled option must NOT be false (default is true) in context class.
The following POCO entity meets all of the above requirements to become a dynamic proxy entity at runtime.
public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public byte[]  Photo { get; set; }
    public decimal Height { get; set; }
    public float Weight { get; set; }
        
    public virtual StudentAddress StudentAddress { get; set; }
    public virtual Grade Grade { get; set; }
}
Note: By default, dynamic proxy is enabled for every entity. However, you can disable dynamic proxy by setting context.Configuration.ProxyCreationEnabled = false; in the context class.
At runtime, EF API will create an instance of dynamic proxy for the above Studententity. The type of dynamic proxy for Student will be System.Data.Entity.DynamicProxies.Student, as shown below:

Use ObjectContext.GetObjectType() to find the underlying wrapped type by the dynamic proxy as shown below:

What is an Entity in Entity Framework?

An entity in Entity Framework is a class in the domain of your application which is included as a DbSet<TEntity> type property in the derived context class. EF API maps each entity to a table and each property of an entity to a column in the database.
For example, the following Student, StudentAddress and Grade are domain classes in the school application.
public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public byte[]  Photo { get; set; }
    public decimal Height { get; set; }
    public float Weight { get; set; }
        
    public StudentAddress StudentAddress { get; set; }
    public Grade Grade { get; set; }
}

public partial class StudentAddress
{
    public int StudentID { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    
    public Student Student { get; set; }
}

public class Grade
{
    public int GradeId { get; set; }
    public string GradeName { get; set; }
    public string Section { get; set; }

    public ICollection<Student> Students { get; set; }
}          
The above classes become entities when they are included as DbSet<TEntity>properties in a context class (the class which derives from DbContext), as shown below.
public class SchoolContext : DbContext
{
    public SchoolContext()
    {

    }

    public DbSet<Student> Students { get; set; }
    public DbSet<StudentAddress> StudentAddresses { get; set; }
    public DbSet<Grade> Grades { get; set; }
}
In the above context class, Students, StudentAddresses, and Grades properties of type DbSet<TEntity> are called entity sets. The Student, StudentAddress, and Grade are entities (also known as entity types).
An Entity can include two types of properties: Scalar Properties and Navigation Properties.

Scalar Property

The primitive type properties are called scalar properties. A scalar property stores the actual data. a scalar property maps to a single column in the database table.
The navigation property represents a relationship to another entity.
There are two types of navigation properties: Reference Navigation and Collection Navigation

Reference Navigation Property

If an entity includes a property of entity type, it is called a Reference Navigation Property. It represents multiplicity of one (1).

Collection Navigation Property

If an entity includes a property of collection type, it is called a collection navigation property. It represents multiplicity of many (*).
The following figure illustrates the properties of entities:

Context Class in Entity Framework

The context class in Entity Framework is a class which derives from DbContext in EF 6 and EF Core both. It is an important class in Entity Framework, which represents a session with the underlying database.
The following SchoolContext class is an example of a context class.
public class SchoolContext : DbContext
{
    public SchoolContext()
    {

    }
        
    public DbSet<Student> Students { get; set; }
    public DbSet<StudentAddress> StudentAddresses { get; set; }
    public DbSet<Grade> Grades { get; set; }
        
} 
In the above example, the SchoolContext class is derived from DbContext, which makes it a context class. It also includes an entity set for Student, StudentAddress, and Grade entities.
The context class is used to query or save data to the database. It is also used to configure domain classes, database related mappings, change tracking settings, caching, transaction etc.