Book Image

Entity Framework Core Cookbook - Second Edition

By : Ricardo Peres
Book Image

Entity Framework Core Cookbook - Second Edition

By: Ricardo Peres

Overview of this book

Entity Framework is a highly recommended Object Relation Mapping tool used to build complex systems. In order to survive in this growing market, the knowledge of a framework that helps provide easy access to databases, that is, Entity Framework has become a necessity. This book will provide .NET developers with this knowledge and guide them through working efficiently with data using Entity Framework Core. You will start off by learning how to efficiently use Entity Framework in practical situations. You will gain a deep understanding of mapping properties and find out how to handle validation in Entity Framework. The book will then explain how to work with transactions and stored procedures along with improving Entity Framework using query libraries. Moving on, you will learn to improve complex query scenarios and implement transaction and concurrency control. You will then be taught to improve and develop Entity Framework in complex business scenarios. With the concluding chapter on performance and scalability, this book will get you ready to use Entity Framework proficiently.
Table of Contents (15 chapters)
Entity Framework Core Cookbook - Second Edition
Credits
About the Author
About the Reviewer
www.PacktPub.com
Preface
Index

References not eagerly fetched are lost


If you don't explicitly ask for related entities when you load an entity, you won't be able to do it later.

Problem

Object-Relational Mappers (ORMs) typically have a feature called lazy loading. Lazy loading means that when an entity is loaded from the database, all its relations (one-to-one, one-to-many, many-to-one, many-to-many) do not necessarily need to be loaded too. When they are first accessed, the ORM will issue a query and retrieve the records. This is interesting, because we do not need to pay the extra cost of loading potentially a lot of records if we are not going to use them. On the other hand, it requires that a connection is always available when the lazy properties are first accessed, otherwise their data cannot be retrieved.

So, here's the catch: Entity Framework Core 1.0 does not have lazy loading. It will come in a future version. What happens, then? Let's imagine we have the following class model:

using System;
using System.Collections.Generic;
namespace BusinessLogic
{
    public class Blog
    {
        public int BlogId { get; set; }
        public string Name { get; set; }
        public DateTime CreationDate { get; set; }
        public string Url { get; set; }
        public ICollection<Post> Posts { get; set; } 
    }
    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public DateTime Timestamp { get; set; }
        public string Body { get; set; }
        public Blog Blog { get; set; }
        public ICollection<Comment> Comments { get; set; }
    }
}

See what happens if you execute a query for the Blog class, such as this one:

var blogs = ctx.Blogs.ToList();

You will retrieve all the blogs in the database, but on each of them, the Posts collection will be null, even for those blogs that do have posts! This is an example of a not loaded one-to-many relationship.

How to solve it…

This is caused by the lack of the lazy loading feature. Since Entity Framework wasn't instructed to fetch the associated posts, it won't do it. The solution is to eagerly fetch them in the query:

var blogsWithPosts = ctx
    .Blogs
    .Include(b => b.Posts)
    .ToList();
This way, all of the posts will be retrieved alongside the blogs.

The same will happen for many-to-one relationships, asking for all posts will not bring along their blogs:

var posts = ctx.Posts.ToList();

We also need to explicitly ask for the Blog property to be included:

var postsWithBlogs = ctx
    .Posts
    .Include(p => p.Blog)
    .ToList();

If you look at the SQL query that was produced, you will see that it generates a LEFT JOIN clause, bringing together the columns for both the Blog and Posts tables.

The Include extension method can even be used to eagerly load multiple levels, for example:

var postsWithBlogsAndComments = ctx
    .Posts
    .Include(p => p.Blog)
    .Include(p => p.Comments)
    .ToList();

Note

Not asking for a relation to be retrieved will cause its corresponding property to be null, so be aware of it.