2012-04-11 3 views
13

Я использую Entity Framework 4.2 (первый код) для доступа к моей базе данных. Я был в предположении, что если я запрошу объект, использующий SingleOrDefault, он будет запрашивать базу данных только в том случае, если объект еще не отслеживается, но это, похоже, не так. С другой стороны, метод Find, похоже, делает это. Проблема с Find заключается в том, что она не позволяет мне загружать связанные данные.Код элемента Entity Framework First Find vs SingleOrDefault (Eager Loading)

Есть ли способ использовать метод Find, но также и загружать данные? В качестве примера, я хочу, чтобы загрузить книгу и все его отзывы:

// 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); 

С SingleOrDefault я могу загрузить обзоры, когда я получаю книгу, используя 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); 

Есть ли способ получить поведение Find с энергичной загрузкой SingleOrDefault?

ответ

11

Метод Find предназначен для поиска одного объекта по ключу. Метод SingleOrDefault предназначен для выполнения запроса. Желаемая загрузка может быть только частью запроса, который действительно выполняется в базе данных, поэтому он не может использоваться с Find.

В качестве временного решения можно переписать следующим образом:

// 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); 
} 
+0

Не знал, что это местное свойство существует. Благодаря! – Dismissile

+0

Привет, а что касается скорости операции, найдите vs SingleOrDefault, чтобы получить информацию об объекте? – Patrick

0

Если функция lazy-load включена, Find найдет для вас работу. Попробуйте следующее:

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

Проверьте значение для переменной «n». EF должен загружать коллекцию при первом доступе к ней.

+2

Его точка является то, что он не хочет использовать ленивый загрузки и хочет, чтобы они хотят загружены. –