Как работает ObjectStateManager.GetObjectStateEntries().Select().OfType()?

#c# #entity-framework

#c# #сущность-фреймворк #entity-framework

Вопрос:

Я пытаюсь понять механизм, который заставляет работать этот код, который я взял из другого вопроса SO:

         List<ResourceType> ResourceTypes2 =
            this.ObjectStateManager
                .GetObjectStateEntries(EntityState.Added)
                .Select(entry => entry.Entity)
                .OfType<ResourceType>().ToList();
  

Является ли приведенное выше запросом объекта или запросом EF?

Причина, по которой я спрашиваю, заключается в том, что я использую его с таблицей, в которой хранится > 100 тысяч строк, и я хочу убедиться, что ей не нужно выполнять какое-то перечисление строк.

В качестве побочного вопроса, который у меня есть, каковы мысли об использовании вышеупомянутого механизма для реализации средства обновления, которое работает, позволяя клиентскому коду просто удалять, а затем добавлять в контекст, но при сохранении сравнивает удаленное с добавленным для достижения обновлений, где строка уже существует? Это был бы «режим», в который помещается контекст, чтобы не иметь побочной семантики.

Комментарии:

1. Это ссылка на объекты в структурах данных ObjectContext / StateManager в памяти (потому что это не IQueryable , как объяснено в ответе @rich.okelly) и не будет выдавать никаких запросов к базе данных. К вашей идее «Upsert»: я не вижу, в чем польза от этой процедуры, и хотел бы сказать: не защищайте клиентов от понимания того, как правильно работать с EF. Если им нужно обновить, они должны использовать механизмы для этого (загрузка из базы данных / Прикрепление / ApplyCurrentValues / Отслеживание изменений и т.д.) И не вызывать неуклюжие пары DeleteObject / AddObject.

2. может быть, я что-то упускаю — я, кажется, единственный, кого я знаю, который ненавидит вводить код снова и снова, чтобы увидеть, существует ли объект, и добавить его, если да, и обновить его с умом…. это утомительный шаблон, верно?

Ответ №1:

Это очень сильно зависит от возвращаемого типа this.ObjectStateManager .GetObjectStateEntries(EntityState.Добавлено)

Если он возвращает IEnumerable, любые последующие операции будут использовать реализации LinqToObjects, тогда как если он возвращает IQueryable, вы будете использовать реализации EF.

Лично мне не понравилась бы идея пользовательского механизма Upsert, поскольку это усложнило бы процесс обучения для всех, кто хочет разработать ваш код в будущем, но это только мое мнение. Для обсуждения плюсов и минусов механизма я бы предложил отдельный вопрос или сообщение в разделе обсуждения.

Надеюсь, это поможет.