Код элемента Entity Framework First Find vs SingleOrDefault (Eager Loading)
Я использую Entity Framework 4.2 (первый код) для доступа к моей базе данных. Я был в предположении, что если я запрошу объект, использующий SingleOrDefault
, он будет запрашивать только базу данных, если объект еще не отслеживается, но это, похоже, не так. С другой стороны, метод Find
, похоже, делает это. Проблема с Find
заключается в том, что она не позволяет мне загружать связанные данные.
Есть ли способ использовать метод 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
?
Ответы
Ответ 1
Метод 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);
}
Ответ 2
Если функция lazy-load включена, Find найдет для вас работу. Попробуйте следующее:
Book book = context.Books.Find(1);
int n = book.Reviews.Count;
Проверьте значение для переменной "n". EF должен загружать коллекцию при первом доступе к ней.