Первое, что вы можете сделать, - отключить отслеживание изменений, поскольку вы не меняете никаких данных в своем коде. Это предотвращает, что загруженные объекты привязываются к контексту:
Для DbContext
(EF> = 4.1):
var inputs = contex.AIMRInputs.AsNoTracking()
.Where(x => x.Input_Type == 1);
И:
var data = contex.Values.AsNoTracking()
.Where(x => x.InputID == input.InputID)
.OrderBy(x => x.TimeStamp)
.ToList();
Редактировать
Для EF 4.0, вы можете оставить свои запросы, как они есть, но добавьте следующее в качестве первых двух строк в блоке using
:
contex.AIMRInputs.MergeOption = MergeOption.NoTracking;
contex.Values.MergeOption = MergeOption.NoTracking;
Это отключает отслеживание изменений для ObjectContext
.
Edit 2
... особенно ссылается на комментарий @James Reategui в ниже этой AsNoTracking
уменьшает объем памяти:
Это часто верно (как в модели/запросе этого вопроса), но не всегда! Фактически использование AsNoTracking
может быть контрпродуктивным в отношении использования памяти.
Что делает AsNoTracking
, когда объекты материализуются в памяти?
Первый: он не прикрепляет объект к контексту и, следовательно, не создает записи в диспетчере состояний контекста. Эти записи потребляют память. При использовании POCOs записи содержат моментальный снимок значений свойства объекта, когда он был сначала загружен/присоединен к контексту - в основном копия всех (скалярных) свойств в дополнение к самому объекту. Таким образом, суммарная память занимает (примерно) вдвое больше, чем размер объекта, когда AsNoTracking
не применяется.
Second: С другой стороны, когда сущности не привязаны к контексту, EF не может использовать преимущества сопоставления идентичности между значениями ключей и идентификаторами объектов.Это означает, что объекты с одним и тем же ключом будут реализованы многократно, что приводит к дополнительной памяти, но без использования AsNoTracking
EF гарантирует, что объект материализуется только один раз за значение ключа.
Вторая точка становится особенно важной, когда загружаются связанные объекты. Простой пример:
Скажем, у нас есть Order
и Customer
, а заказ имеет одного клиента Order.Customer
. Скажем, объект Order
имеет размер 10 байт и объект Customer
размером 20 байт. Теперь мы запускаем этот запрос:
var orderList = context.Orders
.Include(o => o.Customer).Take(3).ToList();
И предположим, что все 3 загруженных заказа имеют один и тот же клиент. Потому что мы не отключить отслеживание EF материализуются:
- 3 заказы объектов = 3x10 = 30 байт
- 1 объект клиента = 1x20 = 20 байт (так как контекст определяет, что клиент является одинаковым для всех 3 заказы материализуется только один объект клиента) записей снимка
- 3 порядка с исходными значениями = 3х10 = 30 байт запись
- 1 снимок клиента с исходными значениями = 1x20 = 20 байт
Сумма: 100 байт
(Для простоты я предполагаю, что элементы контекста с скопированными значениями свойств имеют один и тот же размер, как и сами субъекты.)
Теперь мы запустим запрос с ограниченными возможностями отслеживания изменений:
var orderList = context.Orders.AsNoTracking()
.Include(o => o.Customer).Take(3).ToList();
материализованные данные: (!)
- 3 порядка объектов = 3x10 = 30 байт
- 3 объектов клиента = 3x 20 = 60 байт (Нет тождественное отображение = несколько объектов для каждого ключа, все три объекта, клиент будет иметь те же значения свойств, но они все еще находятся три объекта в памяти)
- Нет записей моментальных
Сумма: 90 байт
Таким образом, используя AsNoTracking
, запрос потреблял 10 байт меньше памяти в этом случае.
Теперь же расчет с 5 порядков (Take(5)
), снова все заказы имеют один и тот же клиент:
Без AsNoTracking
:
- 5 порядков объекты = 5x10 = 50 байт
- 1 объект клиента = 1x20 = 20 байт
- 5 записей моментального снимка с первоначальными значениями = 5x10 = 50 байт
- 1 пользовательский запись эр снимок с исходными значениями = 1x20 = 20 байт
Сумма: 140 байт
С AsNoTracking
:
- 5 порядков объектов = 5x10 = 50 байт
- 5 клиентов (!) объекты = 5x20 = 100 байт
- Нет записей о снимках
Сумма: 150 байт
На этот раз с использованием AsNoTracking
было на 10 байт дороже.
Цифры выше очень грубые, но где-то точка безубыточности, где использование AsNoTracking
может потребоваться больше памяти.
Разница в потреблении памяти между использованием AsNoTracking
или не сильно зависит от запроса, отношений в модели и конкретных данных, загружаемых запросом. Например: AsNoTracking
всегда будет лучше использовать память, когда заказы в примере выше всех (или в основном) имеют разных клиентов.
Заключение: AsNoTracking
в первую очередь предназначен как инструмент для улучшения запроса производительность, а не использование памяти. Во многих случаях он также потребляет меньше памяти. Но не удивляйтесь, если конкретный запрос требует больше памяти с AsNoTracking
. В конце вы должны измерить объем памяти для твердого решения в пользу или против AsNoTracking
.
Нужен ли вызов ToList()? Вы можете уйти, не используя его, и, возможно, уменьшить распределение памяти таким образом. – KingCronus
В этом отношении, зачем это сортировать, если вы просто хотите проверить, равен ли счет? вместо этого вы можете просто добавить 'Any()' после предложения where. Если нет элементов, он возвращает false, иначе true. Ему даже не нужно перебирать первый элемент в перечислимом (который проходит через место). – Servy
нет, я удалил toList(), но это то же самое, мне нужно сделать sth на этих данных, поэтому мне нужно downlaod их всех не только infromation, сколько их из них. – kosnkov