SingleOrDefault vs. Entity Framework Code First Find (Eager Loading)

c# ef-code-first entity-framework

Question

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 ?

1
14
2/12/2015 11:18:24 AM

Accepted Answer

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);
}
13
4/11/2012 7:44:27 PM

Popular Answer

If lazy-loading is enable Find will work for you. Try this:

Book book = context.Books.Find(1);
int n = book.Reviews.Count;

Check the value for the "n" variable. EF must load the collection when you access it first time.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow