Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Code First Find vs SingleOrDefault (Eager Loading)

I'm using Entity Framework 4.2 (Code First) to access my database. I was under the assumption that if I queried an entity using SingleOrDefault it would only query the database if the entity was not already being tracked, but this does not appear to be the case. The Find method on the other hand, does appear to be doing this. The problem with Find is that it doesn't appear to allow me to load related data.

Is there a way to use the Find method but also eagerly load data ? As an example, I want to load a book and all of its reviews:

// Load book from the database
Book book = context.Books.Find(1); 
context.Entry<Book>(book).Collection<Review>.Load(); // Book.Reviews is now populated

// Load book from the change tracker
// This will include all Reviews as well
Book book2 = context.Books.Find(1);

With SingleOrDefault I can load the Reviews when I get the book using Include:

// Load book + reviews from the database
Book book = Book.Include("Reviews").SingleOrDefault(b => b.Id == 1);

// Doing the same thing again requeries the database
Book book2 = Book.Include("Reviews").SingleOrDefault(b => b.Id == 1);

Is there a way to get the behavior of Find with the eager loading of SingleOrDefault ?

like image 779
Dismissile Avatar asked Apr 11 '12 17:04

Dismissile


People also ask

How do I set eager loading in Entity Framework?

Eager loading is the process whereby a query for one type of entity also loads related entities as part of the query. Eager loading is achieved by use of the Include method. For example, the queries below will load blogs and all the posts related to each blog. Include is an extension method in the System.

What is the difference between eager and lazy loading in Entity Framework?

While lazy loading delays the initialization of a resource, eager loading initializes or loads a resource as soon as the code is executed. Eager loading also involves pre-loading related entities referenced by a resource.

What is the way of loading data in Entity Framework?

Entity Framework Core allows you to use the navigation properties in your model to load related entities. There are three common O/RM patterns used to load related data. Eager loading means that the related data is loaded from the database as part of the initial query.

What is lazy loading and eager loading in Entity Framework?

Lazy loading will produce several SQL calls while Eager loading may load data with one "more heavy" call (with joins/subqueries). For example, If there is a high ping between your web and sql servers you would go with Eager loading instead of loading related items 1-by-1 with lazy Loading.


1 Answers

The Find method is for searching single entity by key. The SingleOrDefault method is for executing query. Eager loading can be only part of the query which is really executed on the database so it cannot be used with Find.

As a workaround you can rewrite it this way:

// This will check only on in-memory collection of loaded entities
Book book = context.Books.Local.SingleOrDefault(b => b.Id == 1);
if (book == null)
{
    book = context.Books.Include(b => b.Review).SingleOrDefault(b => b.Id == 1);
}
like image 161
Ladislav Mrnka Avatar answered Sep 22 '22 15:09

Ladislav Mrnka