Entity Framework (EF)

Entity Framework (EF) is a set of Data Access technologies for .NET applications that enables developers to interact with relational data using domain-specific objects, eliminating the need for most of the data-access code that developers traditionally need to write.

Table of Contents

Introduction to Entity Framework

Entity Framework is Microsoft's object-relational mapper (ORM) for the .NET framework. It allows developers to work with databases using .NET objects, simplifying data access and reducing boilerplate code. EF translates queries written in LINQ (Language Integrated Query) into SQL statements that are executed against the database.

Key benefits of using Entity Framework include:

EF Core vs. EF6

Entity Framework has evolved significantly over the years. The two primary versions you'll encounter are:

For new projects, always consider using EF Core.

Getting Started

To start using Entity Framework Core, you typically need to install the necessary NuGet packages. For a basic setup, you'll need:

dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools

Next, you'll define your data model (your entities) and a DbContext class, which represents a session with the database and allows you to query and save data.

Example: Defining an Entity

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public int BlogId { get; set; }
    public virtual Blog Blog { get; set; }
}

Example: Defining a DbContext

using Microsoft.EntityFrameworkCore;

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=Blogging;Trusted_Connection=True;");
    }
}

Code-First Approach

The Code-First approach allows you to define your domain model classes first, and then EF Core creates the database schema based on your classes. This is often the preferred approach for new development.

You define your entities and DbContext as shown in the "Getting Started" section. Then, you use EF Core Migrations to generate and apply the database schema.

Database-First Approach

With the Database-First approach, you start with an existing database, and EF Core generates the model classes and DbContext from it. This is useful when you're working with legacy databases or when a DBA provides you with a schema.

You can use the EF Core Power Tools (available as a Visual Studio extension) or the command-line interface to scaffold your model from an existing database.

Model-First Approach

The Model-First approach involves designing your conceptual model using a visual designer (like the one in Visual Studio), and then EF generates both the code and the database schema from that model. This approach is less common now, with EF Core favoring Code-First.

Querying Data

Entity Framework allows you to query your data using LINQ. The DbContext exposes DbSet<TEntity> properties, which represent collections of entities in the database.

Example: Fetching all blogs

using (var context = new BloggingContext())
{
    var blogs = context.Blogs.ToList();
    foreach (var blog in blogs)
    {
        Console.WriteLine($"Blog URL: {blog.Url}");
    }
}

Example: Filtering and Including Related Data

using (var context = new BloggingContext())
{
    var aspNetBlogs = context.Blogs
        .Where(b => b.Url.Contains("asp.net"))
        .OrderBy(b => b.Url)
        .ToList();

    var firstBlogWithPosts = context.Blogs
        .Include(b => b.Posts) // Eagerly load Posts
        .FirstOrDefault();
}

See the LINQ documentation for more details on query syntax.

Saving Changes

After modifying entities (adding, updating, or deleting), you call SaveChanges() on the DbContext to persist those changes to the database.

Example: Adding a new blog

using (var context = new BloggingContext())
{
    var newBlog = new Blog { Url = "https://example.com/newblog" };
    context.Blogs.Add(newBlog);
    context.SaveChanges(); // Inserts the new blog
}

Example: Updating a blog

using (var context = new BloggingContext())
{
    var blogToUpdate = context.Blogs.Find(1); // Assuming a blog with ID 1 exists
    if (blogToUpdate != null)
    {
        blogToUpdate.Url = "https://example.com/updatedblog";
        context.SaveChanges(); // Updates the blog's URL
    }
}

Example: Deleting a blog

using (var context = new BloggingContext())
{
    var blogToDelete = context.Blogs.Find(2); // Assuming a blog with ID 2 exists
    if (blogToDelete != null)
    {
        context.Blogs.Remove(blogToDelete);
        context.SaveChanges(); // Deletes the blog
    }
}

Migrations

EF Core Migrations are a way to incrementally update your database schema to keep it in sync with your data model. They allow you to evolve your database schema over time without losing data.

Common commands:

Migrations are stored as C# classes and can be reviewed and modified.

Advanced Topics

Entity Framework offers many advanced features:

Explore the detailed advanced topics section for in-depth guidance.