Начну с небольшой зарисовки для понимания.
Entity Framework это программная прослойка, которая преобразует ваши запросы в SQL и передает их в реальную базу. Полученные ответы обрабатываются и записываются в виде объектной модели в памяти. Поясню на примере. Т.е. каждый раз, как вы получили что то из БД, оно осело в большом обхекте типа DataContext. Каждый раз, когда вы вызываете SaveChanges все эти загруженные в память объекты просматриваются на предмет не поменялись ли они и, соответственно, не пора ли их записать в базу данных. Т.е. загружая из базы записи в ComboBox стартового окна, вы будите хранить их в памяти до тех пор, пока приложение не закроется. Даже если они вам больше не нужны.
Пусть у нас есть модель из вот такой таблички:
Написав вот такой код:
static void Main(string[] args)
{
ExampleEntities context = new ExampleEntities();
var types = context.Types;
foreach (var item in types)
{
Console.WriteLine("Name = {0}", item.Name);
}
Console.ReadKey();
}
При наличии трех записей в БД, мы вполне логично увидим на экран 3 строки (у меня там названия: "Первый", "Второй", "Третий").
Чуть модифицируем код.
Для начала добавим вот такой метод:
private static void PrintLocalEntitiesCount(ExampleEntities context)
{
Console.WriteLine(
context.ObjectStateManager.GetObjectStateEntries(
EntityState.Added
| EntityState.Modified
| EntityState.Unchanged
).Where(e => e.Entity is Type)
.Count());
}
Он нам позволит смотреть сколько объектов сейчас в "локальной" памяти Entity Model. Теперь вставим три его вызова в основной код:
ExampleEntities context = new ExampleEntities();
PrintLocalEntitiesCount(context);
var types = context.Types;
PrintLocalEntitiesCount(context);
foreach (var item in types)
{
Console.WriteLine("Name = {0}", item.Name);
}
PrintLocalEntitiesCount(context);
Console.ReadKey();
Как вы думаете, что будет выведено на экран каждым из методов печати количества сущностей в локальной объектной модели? Посчитали? Проверьте себя увеличив картинку:
Совпало? Ну даже если программа обманула ваши ожидания, все равно видно, что после выполнения вывода на экран информации о трех типах, они остались в памяти.
Так вот, это все была присказка. Теперь сказка, как сделать так, чтобы и данные вывести на экран, и в памяти их потом не держать?
На самом деле, легко! Все что нужно, это чуть модифицировать запрос.
Вместо:
var types = context.Types;
Написать:
var types = context.Types.AsNoTracking();
Запускаем:
Все. Данные на экране видим, а в локальном кэше их нет. Что и требовалось.
Entity Framework это программная прослойка, которая преобразует ваши запросы в SQL и передает их в реальную базу. Полученные ответы обрабатываются и записываются в виде объектной модели в памяти. Поясню на примере. Т.е. каждый раз, как вы получили что то из БД, оно осело в большом обхекте типа DataContext. Каждый раз, когда вы вызываете SaveChanges все эти загруженные в память объекты просматриваются на предмет не поменялись ли они и, соответственно, не пора ли их записать в базу данных. Т.е. загружая из базы записи в ComboBox стартового окна, вы будите хранить их в памяти до тех пор, пока приложение не закроется. Даже если они вам больше не нужны.
Пусть у нас есть модель из вот такой таблички:
Написав вот такой код:
static void Main(string[] args)
{
ExampleEntities context = new ExampleEntities();
var types = context.Types;
foreach (var item in types)
{
Console.WriteLine("Name = {0}", item.Name);
}
Console.ReadKey();
}
При наличии трех записей в БД, мы вполне логично увидим на экран 3 строки (у меня там названия: "Первый", "Второй", "Третий").
Чуть модифицируем код.
Для начала добавим вот такой метод:
private static void PrintLocalEntitiesCount(ExampleEntities context)
{
Console.WriteLine(
context.ObjectStateManager.GetObjectStateEntries(
EntityState.Added
| EntityState.Modified
| EntityState.Unchanged
).Where(e => e.Entity is Type)
.Count());
}
Он нам позволит смотреть сколько объектов сейчас в "локальной" памяти Entity Model. Теперь вставим три его вызова в основной код:
ExampleEntities context = new ExampleEntities();
PrintLocalEntitiesCount(context);
var types = context.Types;
PrintLocalEntitiesCount(context);
foreach (var item in types)
{
Console.WriteLine("Name = {0}", item.Name);
}
PrintLocalEntitiesCount(context);
Console.ReadKey();
Как вы думаете, что будет выведено на экран каждым из методов печати количества сущностей в локальной объектной модели? Посчитали? Проверьте себя увеличив картинку:
Совпало? Ну даже если программа обманула ваши ожидания, все равно видно, что после выполнения вывода на экран информации о трех типах, они остались в памяти.
Так вот, это все была присказка. Теперь сказка, как сделать так, чтобы и данные вывести на экран, и в памяти их потом не держать?
На самом деле, легко! Все что нужно, это чуть модифицировать запрос.
Вместо:
var types = context.Types;
Написать:
var types = context.Types.AsNoTracking();
Запускаем:
Все. Данные на экране видим, а в локальном кэше их нет. Что и требовалось.
Комментариев нет:
Отправить комментарий