У Entity Framework нет кэша данных на AppDomain, только кеш на экземпляр контекста.
Если вы создаете новый контекст для каждого запроса или запроса, вы начинаете с пустого кеша, а EF будет извлекать данные из базы данных.
Кроме того, термин «кеш на экземпляр контекста» может вводить в заблуждение, поскольку это не означает, что EF не будет запускать запросы к базе данных, если сущности уже загружены в кэш контекста. То, как этот кэш работает и как вы можете использовать его (или нет) является следующее:
Каждый LINQ к Entities запрос на DbSet<T>
или вообще на IQueryable<T>
будет выполнить запрос к базе данных, независимо от того, существуют ли сущности в контексте или нет. Но если объект с тем же ключом, что и запрашиваемый объект, уже существует в контексте, EF выкинет результат этого запроса и вернет экземпляр кэшированного объекта обратно вызывающему.
Это проверяет, существует ли объект с тем же ключом после он выполнил запрос. (Для сложных запросов - например запросов, которые содержат Include
. - он не может сделать эту проверку, прежде чем, потому что он не может знать, какие будут возвращены сущности и значения ключей)
Это поведение по умолчанию (MergeOption
является AppendOnly
). Вы можете изменить это поведение на OverwriteChanges
и другие варианты, я полагаю, но ни один из них не позволит избежать запросов LINQ, которые всегда вызывают запросы к базе данных.
Для запрашивая объект только ее ключом вы можете использовать GetObjectByKey
или Find
(с DbContext
), который будет проверять первый, если объект с помощью этого ключа уже кэшируются в контексте, а затем вернуть этот объект в кэше. Если нет, он будет запускать запрос базы данных для его загрузки.
Вы можете запросить ET ChangeTracker, особенно хорошо поддерживается с DbContext
, где у вас есть доступ к кешу контекста через коллекцию DbSet<T>.Local
.
Проблема заключается в том, что нет никакой логики для автоматического запроса базы данных, если запрос на Local
не возвращает результат. Вы должны написать эту логику вручную. Еще большая проблема заключается в том, что запрос на Local
является LINQ-to-Objects, а не LINQ-to-Entities (Local
не реализует IQueryable<T>
, только IEnumerable<T>
), поэтому вам часто приходится переписывать свои запросы, чтобы действовать на Local
- например вы не можете использовать Include
здесь, вы не можете использовать любой EntityFunctions
, вы получите различное поведение для сравнения строк в отношении чувствительности к регистру, и т.д. и т.п.
Я не думаю, что данные кэшируются в сущности, это всегда запрос DB –